星期日, 1月 30, 2011

[Alfresco] Constants.java

Constants.java
Language: Java
License: GPL
Copyright: (C) 2005-2007 Alfresco Software Limited.
LOC: 74

[Alfresco] ContentModel.java

ContentModel.java
Language: Java
License: GPL
Copyright: (C) 2005-2007 Alfresco Software Limited.
LOC: 171

星期五, 1月 28, 2011

[Alfresco] URL Addressability

有關Alfresco存取 url連結的說明
URL Addressability

星期四, 1月 27, 2011

[Alfresco] Peer-Association 範例

BaseWebServiceSystemTest.java 
使用foundation api範例

[Alfresco] Avatar

--UserManager printProperties--
{http://www.alfresco.org/model/content/1.0}name:myfbphoto.jpg
{http://www.alfresco.org/model/system/1.0}node-dbid:20391
{http://www.alfresco.org/model/system/1.0}store-identifier:SpacesStore
{http://www.alfresco.org/model/content/1.0}content:contentUrl=store://2011/1/14/10/30/a9fc0ee8-f528-40c8-b4f2-f53459120a47.bin|mimetype=image/jpeg|size=13245|encoding=utf-8|locale=zh_TW_
{http://www.alfresco.org/model/content/1.0}modified:2011-01-14T10:30:51.377+08:00
{http://www.alfresco.org/model/system/1.0}node-uuid:100cbbf4-39c3-41cc-8d79-a80b112347a2
{http://www.alfresco.org/model/content/1.0}created:2011-01-14T10:30:51.377+08:00
{http://www.alfresco.org/model/system/1.0}store-protocol:workspace
{http://www.alfresco.org/model/content/1.0}creator:Ken
{http://www.alfresco.org/model/content/1.0}modifier:Ken
associationType:{http://www.alfresco.org/model/content/1.0}avatar
{http://www.alfresco.org/model/content/1.0}path:/{http://www.alfresco.org/model/system/1.0}system/{http://www.alfresco.org/model/system/1.0}people/{http://www.alfresco.org/model/content/1.0}ken/{http://www.alfresco.org/model/content/1.0}myfbphoto.jpg
--/UserManager printProperties--

星期三, 1月 26, 2011

[ZK] comfirm in zk component

使用程式控制替元件加入comfirm javascript。
範例如下:
//removePhoto.setWidgetListener("onClick", "alert('test');");
removePhoto.setWidgetListener("onClick", "if(!confirm('Remove Your Picture?')){evt.stop({au:true});}");

A client-side event listener could stop the sending of a widget event to the server by invoking Event.stop(Map) with {au:true}, such as

evt.stop({au: true});

Reference:
ZK Client-side Reference/Notifications/Widget Events
ZK Client-side Reference/Communication/AU Requests/Client-side Firing

星期一, 1月 24, 2011

[Alfresco] AdministrationServiceSystemTest.java

AdministrationServiceSystemTest.java
Language: Java
License: GPL
Copyright: (C) 2005-2007 Alfresco Software Limited.
LOC: 304
使用alfresco webservice提供簡單的User management測試範例,值得參考。


Reference:
AdministrationServiceSystemTest.java 

星期三, 1月 19, 2011

[ZK] Client Side API

減少server的loading,免不得要使用client的資源。



A UI object visible to a user at the client is hosted by a JavaScript object[1] called a widget (Widget).

Document
ZK Client-side Reference(完整的章節-請讀完)
ZK Client Engine 5.0.5 API is based on JQuery.
Zk.Widget

Event Handle
Widget Events
DOM Events
Client Activity Watches



Example
Small Talks/2010/April/Client Side Programming
ZK5: Client Computing with ZUML

星期二, 1月 18, 2011

[ZK] BorderLayout Attributes

ZK Layout attribute specification table:

星期日, 1月 16, 2011

[Alfresco] User Node

 使用者的profile描述:

星期五, 1月 14, 2011

星期四, 1月 13, 2011

[Asp.Net] 在Asp.net輸出logging

在asp.net使用Console.WriteLine("logging"); 是看不到的。
請改用使用:

System.Diagnostics.Debug.WriteLine("logging");

[Alfresco] Print User Site Node

紅色標記為siteModel.xml內所定義的Type的properties

1.列印一個使用者(Ken)SiteNode:

[網路工具] Fiddler2

用來分析https的好工具。

星期三, 1月 12, 2011

[Windows] 使用 net use 指令連線網路磁碟機

如果想要把連線指定到你本機的磁碟機p:,那可以這樣用
net use p: "\\serverip\foldername" /user:useraccount password /persistent:no

星期一, 1月 10, 2011

星期日, 1月 09, 2011

[Asp.Net] Https using WebClient

等入驗證之前先補上這一段就可以取得加密的憑證

即可用正常的webclient
try
{
System.Net.ServicePointManager.ServerCertificateValidationCallback =
delegate(object senderX, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
};
HtmlText = wc.DownloadString(wc.BaseAddress);

}
catch
{
System.Environment.Exit(System.Environment.ExitCode);
}

[Alfresco] Node References and Store Protocols

了解Alfresco的NodeRef與StoreRef的差異。

Reference:
Node References and Store Protocols

SourceCode:
NodeArchiveServiceImpl.java 
NodeRefTest.java
ArchiveAndRestoreTest.java

星期二, 1月 04, 2011

[Alfresco] Content Domain Model Notes

這隻ContentModel.java實作Alfresco Data Domain Model相關的QNAME,
簡單來說,就是把各個Data Domain Model內定義的QNAME,
用程式控制來取得完整的QName String

QNAME Format:{NameSapce}Name
Example:{http://www.alfresco.org/model/content/1.0}content


簡單分析contentModel.xml的結構:
model(root)
  --imports
  --namespaces
  --constrains
  --types
     --title
     --parent
     --archive
     --association
        --child-association
     --properties
        --property
   --aspects
      --aspect
      --title(aspect標題)
      --properties(aspect擁有的屬性集)
        --property
           --title(property標題)
           --type(屬性資料型態)
           --default(資料是否有預設值)
           --protected
           --index
           --mandatory
  --mandotory-aspects
     --aspect
  --associations
     --association
     --child-association

看ContentModel.xml原始碼

Reference:
ContentModel.java

[Alfresco] How to rename User Groups using web services? (4)

重新命名群組,下面程式尚未測試過,僅供參考。

[Alfresco] Node Testing

做了一些實驗的資料:

[Alfresco] delete a specific file without archival

If you want to delete a specific file without archival, then you can just apply the sys:temporary aspect prior to deletion.


nodeService.addAspect(nodeRef, ContentModel.ASPECT_TEMPORARY); 
PS: NodeService is not exposed as WebService API.

Reference:
Archive Store Lucene query
Invoking NodeService instance
Disabling Document Archival


[Alfresco] CMIS (Content Management Interoperability Services)

CMIS (Content Management Interoperability Services) is a standard for improving interoperability between ECM systems. It specifies a domain model plus a set of services and protocol bindings for Web Services (SOAP) and AtomPub.


Reference:
OpenCMIS Cookbook(Sample Code)
CMIS Webservice Wiki(新增的CMIS WS服務)

星期一, 1月 03, 2011

[Alfresco] NodeArchiveServiceImpl

/*
 * Copyright (C) 2005-2010 Alfresco Software Limited.
 *
 * This file is part of Alfresco
 *
 * Alfresco is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Alfresco is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see .
 */
package org.alfresco.repo.node.archive;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.batch.BatchProcessWorkProvider;
import org.alfresco.repo.batch.BatchProcessor;
import org.alfresco.repo.batch.BatchProcessor.BatchProcessWorker;
import org.alfresco.repo.lock.JobLockService;
import org.alfresco.repo.lock.LockAcquisitionException;
import org.alfresco.repo.node.archive.RestoreNodeReport.RestoreStatus;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.RetryingTransactionHelper;
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.util.EqualsHelper;
import org.alfresco.util.VmShutdownListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Implementation of the node archive abstraction.
 * 
 * @author Derek Hulley
 */
public class NodeArchiveServiceImpl implements NodeArchiveService
{
    private static final QName LOCK_QNAME = QName.createQName(NamespaceService.ALFRESCO_URI, "NodeArchive");
    private static final long LOCK_TTL = 60000;
    
    private static final String MSG_BUSY = "node.archive.msg.busy";
    
    private static Log logger = LogFactory.getLog(NodeArchiveServiceImpl.class);
    
    private NodeService nodeService;
    private SearchService searchService;
    private TransactionService transactionService;
    private JobLockService jobLockService;

    public void setNodeService(NodeService nodeService)
    {
        this.nodeService = nodeService;
    }

    public void setTransactionService(TransactionService transactionService)
    {
        this.transactionService = transactionService;
    }

    public void setSearchService(SearchService searchService)
    {
        this.searchService = searchService;
    }

    public NodeRef getStoreArchiveNode(StoreRef originalStoreRef)
    {
        return nodeService.getStoreArchiveNode(originalStoreRef);
    }

    public void setJobLockService(JobLockService jobLockService)
    {
        this.jobLockService = jobLockService;
    }

    public NodeRef getArchivedNode(NodeRef originalNodeRef)
    {
        StoreRef orginalStoreRef = originalNodeRef.getStoreRef();
        NodeRef archiveRootNodeRef = nodeService.getStoreArchiveNode(orginalStoreRef);
        // create the likely location of the archived node
        NodeRef archivedNodeRef = new NodeRef(
                archiveRootNodeRef.getStoreRef(),
                originalNodeRef.getId());
        return archivedNodeRef;
    }
    
    /**
     * Get all the nodes that were archived from the given store.
     * 
     * @param originalStoreRef      the original store to process
     * @param skipCount             the number of results to skip (used for paging)
     * @param limit                 the number of items to retrieve or -1 to get the all    
     * 
     * @deprecated          To be replaced with a limiting search against the database
     */
    private ResultSet getArchivedNodes(StoreRef originalStoreRef, int skipCount, int limit)
    {
        // Get the archive location
        NodeRef archiveParentNodeRef = nodeService.getStoreArchiveNode(originalStoreRef);
        StoreRef archiveStoreRef = archiveParentNodeRef.getStoreRef();
        // build the query
        String query = String.format("PARENT:\"%s\" AND ASPECT:\"%s\"", archiveParentNodeRef, ContentModel.ASPECT_ARCHIVED);
        // search parameters
        SearchParameters params = new SearchParameters();
        params.addStore(archiveStoreRef);
        params.setLanguage(SearchService.LANGUAGE_LUCENE);
        params.setQuery(query);
        params.setSkipCount(skipCount);
        params.setMaxItems(limit);
        // get all archived children using a search
        ResultSet rs = searchService.query(params);
        // done
        return rs;
    }
    
    /**
     * @return                      Returns a work provider for batch processing
     * 
     * @since 3.3.4
     */
    private BatchProcessWorkProvider getArchivedNodesWorkProvider(final StoreRef originalStoreRef, final String lockToken)
    {
        return new BatchProcessWorkProvider()
        {
            private VmShutdownListener vmShutdownLister = new VmShutdownListener("getArchivedNodesWorkProvider");
            private Integer workSize;
            private int skipResults = 0;
            public synchronized int getTotalEstimatedWorkSize()
            {
                if (workSize == null)
                {
                    workSize = Integer.valueOf(0);
                    ResultSet rs = null;
                    try
                    {
                        rs = getArchivedNodes(originalStoreRef, 0, -1);
                        workSize = rs.length();
                    }
                    catch (Throwable e)
                    {
                        logger.error("Failed to get archive size", e);
                    }
                    finally
                    {
                        if (rs != null) { rs.close(); }
                    }
                }
                return workSize;
            }
            public synchronized Collection getNextWork()
            {
                if (vmShutdownLister.isVmShuttingDown())
                {
                    return Collections.emptyList();
                }
                // Make sure we still have the lock
                try
                {
                    // TODO: Replace with joblock callback mechanism that provides shutdown hints
                    jobLockService.refreshLock(lockToken, LOCK_QNAME, LOCK_TTL);
                }
                catch (LockAcquisitionException e)
                {
                    // This is OK.  We don't have the lock so just quit
                    return Collections.emptyList();
                }
                
                Collection results = new ArrayList(100);
                ResultSet rs = null;
                try
                {
                    rs = getArchivedNodes(originalStoreRef, skipResults, 100);
                    for (ResultSetRow row : rs)
                    {
                        results.add(row.getNodeRef());
                    }
                    skipResults += results.size();
                }
                finally
                {
                    if (rs != null) { rs.close(); }
                }
                return results;
            }
        };
    }

    /**
     * This is the primary restore method that all restore methods fall back on.
     * It executes the restore for the node in a separate transaction and attempts to catch
     * the known conditions that can be reported back to the client.
     */
    public RestoreNodeReport restoreArchivedNode(
            final NodeRef archivedNodeRef,
            final NodeRef destinationNodeRef,
            final QName assocTypeQName,
            final QName assocQName)
    {
        RestoreNodeReport report = new RestoreNodeReport(archivedNodeRef);
        report.setTargetParentNodeRef(destinationNodeRef);
        try
        {
            // Transactional wrapper to attempt the restore
            RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
            RetryingTransactionCallback restoreCallback = new RetryingTransactionCallback()
            {
                public NodeRef execute() throws Exception
                {
                    return nodeService.restoreNode(archivedNodeRef, destinationNodeRef, assocTypeQName, assocQName);
                }
            };
            NodeRef newNodeRef = txnHelper.doInTransaction(restoreCallback, false, true);
            // success
            report.setRestoredNodeRef(newNodeRef);
            report.setStatus(RestoreStatus.SUCCESS);
        }
        catch (InvalidNodeRefException e)
        {
            report.setCause(e);
            NodeRef invalidNodeRef = e.getNodeRef();
            if (archivedNodeRef.equals(invalidNodeRef))
            {
                // not too serious, but the node to archive is missing
                report.setStatus(RestoreStatus.FAILURE_INVALID_ARCHIVE_NODE);
            }
            else if (EqualsHelper.nullSafeEquals(destinationNodeRef, invalidNodeRef))
            {
                report.setStatus(RestoreStatus.FAILURE_INVALID_PARENT);
            }
            else if (destinationNodeRef == null)
            {
                // get the original parent of the archived node
                ChildAssociationRef originalParentAssocRef = (ChildAssociationRef) nodeService.getProperty(
                        archivedNodeRef,
                        ContentModel.PROP_ARCHIVED_ORIGINAL_PARENT_ASSOC);
                NodeRef originalParentNodeRef = originalParentAssocRef.getParentRef();
                if (EqualsHelper.nullSafeEquals(originalParentNodeRef, invalidNodeRef))
                {
                    report.setStatus(RestoreStatus.FAILURE_INVALID_PARENT);
                }
                else
                {
                    // some other invalid node was detected
                    report.setStatus(RestoreStatus.FAILURE_OTHER);
                }
            }
            else
            {
                // some other invalid node was detected
                report.setStatus(RestoreStatus.FAILURE_OTHER);
            }
        }
        catch (AccessDeniedException e)
        {
            report.setCause(e);
            report.setStatus(RestoreStatus.FAILURE_PERMISSION);
        }
        catch (Throwable e)
        {
            report.setCause(e);
            report.setStatus(RestoreStatus.FAILURE_OTHER);
            logger.error("An unhandled exception stopped the restore", e);
        }
        // done
        if (logger.isDebugEnabled())
        {
            logger.debug("Attempted node restore: "+ report);
        }
        return report;
    }

    /**
     * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
     */
    public RestoreNodeReport restoreArchivedNode(NodeRef archivedNodeRef)
    {
        return restoreArchivedNode(archivedNodeRef, null, null, null);
    }

    /**
     * @see #restoreArchivedNodes(List, NodeRef, QName, QName)
     */
    public List restoreArchivedNodes(List archivedNodeRefs)
    {
        return restoreArchivedNodes(archivedNodeRefs, null, null, null);
    }

    /**
     * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
     */
    public List restoreArchivedNodes(
            List archivedNodeRefs,
            NodeRef destinationNodeRef,
            QName assocTypeQName,
            QName assocQName)
    {
        List results = new ArrayList(archivedNodeRefs.size());
        for (NodeRef nodeRef : archivedNodeRefs)
        {
            RestoreNodeReport result = restoreArchivedNode(nodeRef, destinationNodeRef, assocTypeQName, assocQName);
            results.add(result);
        }
        return results;
    }

    /**
     * Uses batch processing and job locking to purge all archived nodes
     */
    public List restoreAllArchivedNodes(StoreRef originalStoreRef)
    {
        final String user = AuthenticationUtil.getFullyAuthenticatedUser();
        if (user == null)
        {
            throw new IllegalStateException("Cannot restore as there is no authenticated user.");
        }
        
        final List results = Collections.synchronizedList(new ArrayList(1000));
        /**
         * Worker that purges each node
         */
        BatchProcessWorker worker = new BatchProcessor.BatchProcessWorkerAdaptor()
        {
            public void process(NodeRef entry) throws Throwable
            {
                AuthenticationUtil.pushAuthentication();
                try
                {
                    AuthenticationUtil.setFullyAuthenticatedUser(user);
                    if (nodeService.exists(entry))
                    {
                        RestoreNodeReport report = restoreArchivedNode(entry);
                        // Append the results (it is synchronized)
                        results.add(report);
                    }
                }
                finally
                {
                    AuthenticationUtil.popAuthentication();
                }
            }
        };
        doBulkOperation(user, originalStoreRef, worker);
        return results;
    }

    /**
     * Finds the archive location for nodes that were deleted from the given store
     * and attempt to restore each node.
     * 
     * @see NodeService#getStoreArchiveNode(StoreRef)
     * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
     */
    public List restoreAllArchivedNodes(
            StoreRef originalStoreRef,
            NodeRef destinationNodeRef,
            QName assocTypeQName,
            QName assocQName)
    {
        // get all archived children using a search
        ResultSet rs = getArchivedNodes(originalStoreRef, 0, -1);
        try
        {
            // loop through the resultset and attempt to restore all the nodes
            List results = new ArrayList(1000);
            for (ResultSetRow row : rs)
            {
                NodeRef archivedNodeRef = row.getNodeRef();
                RestoreNodeReport result = restoreArchivedNode(archivedNodeRef, destinationNodeRef, assocTypeQName, assocQName);
                results.add(result);
            }
            // done
            if (logger.isDebugEnabled())
            {
                logger.debug("Restored " + results.size() + " nodes into store " + originalStoreRef);
            }
            return results;
        }
        finally
        {
            rs.close();
        }
    }

    /**
     * This is the primary purge methd that all purge methods fall back on.  It isolates the delete
     * work in a new transaction.
     */
    public void purgeArchivedNode(final NodeRef archivedNodeRef)
    {
        RetryingTransactionHelper txnHelper = transactionService.getRetryingTransactionHelper();
        RetryingTransactionCallback deleteCallback = new RetryingTransactionCallback()         {             public Object execute() throws Exception             {                 try                 {                     nodeService.deleteNode(archivedNodeRef);                 }                 catch (InvalidNodeRefException e)                 {                     // ignore                 }                 return null;             }         };         txnHelper.doInTransaction(deleteCallback, false, true);     }      /**      * @see #purgeArchivedNode(NodeRef)      */     public void purgeArchivedNodes(List archivedNodes)     {         for (NodeRef archivedNodeRef : archivedNodes)         {             purgeArchivedNode(archivedNodeRef);         }         // done     }      /**      * Uses batch processing and job locking to purge all archived nodes      */     public void purgeAllArchivedNodes(StoreRef originalStoreRef)     {         final String user = AuthenticationUtil.getFullyAuthenticatedUser();         if (user == null)         {             throw new IllegalStateException("Cannot purge as there is no authenticated user.");         }                  /**          * Worker that purges each node          */         BatchProcessWorker worker = new BatchProcessor.BatchProcessWorkerAdaptor()         {             public void process(NodeRef entry) throws Throwable             {                 AuthenticationUtil.pushAuthentication();                 try                 {                     AuthenticationUtil.setFullyAuthenticatedUser(user);                     if (nodeService.exists(entry))                     {                         nodeService.deleteNode(entry);                     }                 }                 finally                 {                     AuthenticationUtil.popAuthentication();                 }             }         };         doBulkOperation(user, originalStoreRef, worker);     }          /**      * Do batch-controlled work      */     private void doBulkOperation(final String user, StoreRef originalStoreRef, BatchProcessWorker worker)     {         String lockToken = null;         try         {             // Get a lock to keep refreshing             lockToken = jobLockService.getLock(LOCK_QNAME, LOCK_TTL);             // TODO: Should merely trigger a background job i.e. perhaps it should not be             //       triggered by a user-based thread             BatchProcessor batchProcessor = new BatchProcessor(                     "ArchiveBulkPurgeOrRestore",                     transactionService.getRetryingTransactionHelper(),                     getArchivedNodesWorkProvider(originalStoreRef, lockToken),                     2, 20,                     null, null, 1000);             batchProcessor.process(worker, true);         }         catch (LockAcquisitionException e)         {             throw new AlfrescoRuntimeException(MSG_BUSY);         }         finally         {             try             {                 if (lockToken != null ) {jobLockService.releaseLock(lockToken, LOCK_QNAME); }             }             catch (LockAcquisitionException e)             {                 // Ignore             }         }     } }

其他你感興趣的文章

Related Posts with Thumbnails