mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	125515 slanglois: MNT-16155 Update source headers - add new Copyrights for Java and JSP source files + automatic check in the build git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.1.N/root@125606 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
		
			
				
	
	
		
			533 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			533 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| /*
 | |
|  * #%L
 | |
|  * Alfresco Repository
 | |
|  * %%
 | |
|  * Copyright (C) 2005 - 2016 Alfresco Software Limited
 | |
|  * %%
 | |
|  * This file is part of the Alfresco software. 
 | |
|  * If the software was purchased under a paid Alfresco license, the terms of 
 | |
|  * the paid license agreement will prevail.  Otherwise, the software is 
 | |
|  * provided under the following open source license terms:
 | |
|  * 
 | |
|  * 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 <http://www.gnu.org/licenses/>.
 | |
|  * #L%
 | |
|  */
 | |
| package org.alfresco.repo.domain.node;
 | |
| 
 | |
| import java.io.Serializable;
 | |
| import java.io.UnsupportedEncodingException;
 | |
| import java.util.List;
 | |
| import java.util.zip.CRC32;
 | |
| 
 | |
| import org.alfresco.repo.domain.qname.QNameDAO;
 | |
| import org.alfresco.service.cmr.dictionary.AssociationDefinition;
 | |
| import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
 | |
| import org.alfresco.service.cmr.dictionary.DictionaryService;
 | |
| import org.alfresco.service.cmr.repository.ChildAssociationRef;
 | |
| import org.alfresco.service.namespace.QName;
 | |
| import org.alfresco.util.GUID;
 | |
| import org.alfresco.util.Pair;
 | |
| import org.alfresco.util.ParameterCheck;
 | |
| import org.apache.commons.logging.Log;
 | |
| import org.apache.commons.logging.LogFactory;
 | |
| 
 | |
| /**
 | |
|  * Bean for <b>alf_child_assoc</b> table.
 | |
|  * 
 | |
|  * @author Derek Hulley
 | |
|  * @since 3.4
 | |
|  */
 | |
| public class ChildAssocEntity implements Serializable
 | |
| {
 | |
|     private static final long serialVersionUID = 1L;
 | |
| 
 | |
|     private static final Log logger = LogFactory.getLog(ChildAssocEntity.class);
 | |
|     
 | |
|     private Long id;
 | |
|     private Long version;
 | |
|     private NodeEntity parentNode;
 | |
|     private NodeEntity childNode;
 | |
|     private Long typeQNameId;
 | |
|     private Long childNodeNameCrc;
 | |
|     private String childNodeName;
 | |
|     private Long qnameNamespaceId;
 | |
|     private String qnameLocalName;
 | |
|     private Long qnameCrc;
 | |
|     private Boolean isPrimary;
 | |
|     private int assocIndex;
 | |
|     
 | |
|     // Supplemental query-related parameters
 | |
|     private List<Long> typeQNameIds;
 | |
|     private List<Long> childNodeNameCrcs;
 | |
|     private List<Long> childNodeTypeQNameIds;
 | |
|     private Boolean sameStore;
 | |
|     private boolean ordered;
 | |
|     
 | |
|     /**
 | |
|      * Find a CRC value for the full QName using UTF-8 conversion.
 | |
|      * 
 | |
|      * @param qname                 the association qname
 | |
|      * @return                      Returns the CRC value (UTF-8 compatible)
 | |
|      */
 | |
|     public static Long getQNameCrc(QName qname)
 | |
|     {
 | |
|         CRC32 crc = new CRC32();
 | |
|         try
 | |
|         {
 | |
|             crc.update(qname.getNamespaceURI().getBytes("UTF-8"));
 | |
|             crc.update(qname.getLocalName().getBytes("UTF-8"));
 | |
|         }
 | |
|         catch (UnsupportedEncodingException e)
 | |
|         {
 | |
|             throw new RuntimeException("UTF-8 encoding is not supported");
 | |
|         }
 | |
|         return crc.getValue();
 | |
|         
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Find a CRC value for the association's child node name using UTF-8 conversion.
 | |
|      * 
 | |
|      * @param childNodeName         the child node name
 | |
|      * @return                      Returns the CRC value (UTF-8 compatible)
 | |
|      */
 | |
|     public static Long getChildNodeNameCrc(String childNodeName)
 | |
|     {
 | |
|         CRC32 crc = new CRC32();
 | |
|         try
 | |
|         {
 | |
|             // https://issues.alfresco.com/jira/browse/ALFCOM-1335
 | |
|             crc.update(childNodeName.getBytes("UTF-8"));
 | |
|         }
 | |
|         catch (UnsupportedEncodingException e)
 | |
|         {
 | |
|             throw new RuntimeException("UTF-8 encoding is not supported");
 | |
|         }
 | |
|         return crc.getValue();
 | |
|     }
 | |
| 
 | |
|     private static final String TRUNCATED_NAME_INDICATOR = "~~~";
 | |
| 
 | |
|     /**
 | |
|      * Truncates the association's child node name to 50 characters.
 | |
|      * 
 | |
|      * @param childNodeName         the child node name
 | |
|      * @return                      Returns the potentially truncated value
 | |
|      */
 | |
|     public static String getChildNodeNameShort(String childNodeName)
 | |
|     {
 | |
|         int length = childNodeName.length();
 | |
|         if (length <= 50)
 | |
|         {
 | |
|             return childNodeName;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             StringBuilder ret = new StringBuilder(50);
 | |
|             ret.append(childNodeName.substring(0, 47)).append(TRUNCATED_NAME_INDICATOR);
 | |
|             return ret.toString();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Apply the <b>cm:name</b> to the child association. If the child name is <tt>null</tt> then a GUID is generated as
 | |
|      * a substitute.
 | |
|      * <p>
 | |
|      * Unknown associations or associations that do not require unique name checking will use a GUID for the child
 | |
|      * name and the CRC value used <b>will be negative</b>.
 | |
|      * 
 | |
|      * @param childName the <b>cm:name</b> applying to the association.
 | |
|      */
 | |
|     public static Pair<String, Long> getChildNameUnique(
 | |
|             DictionaryService dictionaryService,
 | |
|             QName assocTypeQName,
 | |
|             String childName)
 | |
|     {
 | |
|         if (childName == null)
 | |
|         {
 | |
|             throw new IllegalArgumentException("Child name may not be null.  Use the Node ID ...");
 | |
|         }
 | |
|         
 | |
|         String childNameNewShort; // 
 | |
|         long childNameNewCrc = -1L; // By default, they don't compete
 | |
| 
 | |
|         AssociationDefinition assocDef = dictionaryService.getAssociation(assocTypeQName);
 | |
|         if (assocDef == null || !assocDef.isChild())
 | |
|         {
 | |
|             if (logger.isWarnEnabled())
 | |
|             {
 | |
|                 logger.warn("No child association of this type could be found: " + assocTypeQName);
 | |
|             }
 | |
|             childNameNewShort = GUID.generate();
 | |
|             childNameNewCrc = -1L * getChildNodeNameCrc(childNameNewShort);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             ChildAssociationDefinition childAssocDef = (ChildAssociationDefinition) assocDef;
 | |
|             if (childAssocDef.getDuplicateChildNamesAllowed())
 | |
|             {
 | |
|                 childNameNewShort = GUID.generate();
 | |
|                 childNameNewCrc = -1L * getChildNodeNameCrc(childNameNewShort);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 String childNameNewLower = childName.toLowerCase();
 | |
|                 childNameNewShort = getChildNodeNameShort(childNameNewLower);
 | |
|                 childNameNewCrc = getChildNodeNameCrc(childNameNewLower);
 | |
|             }
 | |
|         }
 | |
|         return new Pair<String, Long>(childNameNewShort, childNameNewCrc);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Required default constructor
 | |
|      */
 | |
|     public ChildAssocEntity()
 | |
|     {
 | |
|         ordered = false;
 | |
|     }
 | |
| 
 | |
|     @Override
 | |
|     public String toString()
 | |
|     {
 | |
|         StringBuilder sb = new StringBuilder(512);
 | |
|         sb.append("ChildAssocEntity")
 | |
|           .append("[ ID=").append(id)
 | |
|           .append(", typeQNameId=").append(typeQNameId)
 | |
|           .append(", childNodeNameCrc=").append(childNodeNameCrc)
 | |
|           .append(", childNodeName=").append(childNodeName)
 | |
|           .append(", qnameNamespaceId=").append(qnameNamespaceId)
 | |
|           .append(", qnameLocalName=").append(qnameLocalName)
 | |
|           .append(", qnameCrc=").append(qnameCrc)
 | |
|           .append(", parentNode=").append(parentNode)
 | |
|           .append(", childNode=").append(childNode)
 | |
|           .append("]");
 | |
|         return sb.toString();
 | |
|     }
 | |
|     
 | |
|     public ChildAssociationRef getRef(QNameDAO qnameDAO)
 | |
|     {
 | |
|         QName typeQName = qnameDAO.getQName(typeQNameId).getSecond();
 | |
|         QName qname = QName.createQName(qnameDAO.getNamespace(qnameNamespaceId).getSecond(), qnameLocalName);
 | |
|         return new ChildAssociationRef(
 | |
|                 typeQName,
 | |
|                 parentNode.getNodeRef(),
 | |
|                 qname,
 | |
|                 childNode.getNodeRef(),
 | |
|                 isPrimary,
 | |
|                 assocIndex);
 | |
|     }
 | |
|     
 | |
|     public Pair<Long, ChildAssociationRef> getPair(QNameDAO qnameDAO)
 | |
|     {
 | |
|         return new Pair<Long, ChildAssociationRef>(id, getRef(qnameDAO));
 | |
|     }
 | |
| 
 | |
|     public Long getId()
 | |
|     {
 | |
|         return id;
 | |
|     }
 | |
| 
 | |
|     public void setId(Long id)
 | |
|     {
 | |
|         this.id = id;
 | |
|     }
 | |
| 
 | |
|     public Long getVersion()
 | |
|     {
 | |
|         return version;
 | |
|     }
 | |
| 
 | |
|     public void setVersion(Long version)
 | |
|     {
 | |
|         this.version = version;
 | |
|     }
 | |
| 
 | |
|     public NodeEntity getParentNode()
 | |
|     {
 | |
|         return parentNode;
 | |
|     }
 | |
| 
 | |
|     public void setParentNode(NodeEntity parentNode)
 | |
|     {
 | |
|         this.parentNode = parentNode;
 | |
|     }
 | |
| 
 | |
|     public NodeEntity getChildNode()
 | |
|     {
 | |
|         return childNode;
 | |
|     }
 | |
| 
 | |
|     public void setChildNode(NodeEntity childNode)
 | |
|     {
 | |
|         this.childNode = childNode;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * Helper method to set the {@link #setTypeQNameId(Long)}.
 | |
|      * 
 | |
|      * @param qnameDAO                  the DAO to resolve the QName ID
 | |
|      * @param typeQName                 the association type
 | |
|      * @param forUpdate                 <tt>true</tt> if the QName must exist i.e. this
 | |
|      *                                  entity will be used for updates and the type
 | |
|      *                                  <code>QName</code> <b>must</b> exist.
 | |
|      * @return                          <tt>true</tt> if the set worked otherwise <tt>false</tt>
 | |
|      */
 | |
|     public boolean setTypeQNameAll(QNameDAO qnameDAO, QName typeQName, boolean forUpdate)
 | |
|     {
 | |
|         if (forUpdate)
 | |
|         {
 | |
|             typeQNameId = qnameDAO.getOrCreateQName(typeQName).getFirst();
 | |
|             return true;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             Pair<Long, QName> qnamePair = qnameDAO.getQName(typeQName);
 | |
|             if (qnamePair == null)
 | |
|             {
 | |
|                 return false;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 typeQNameId = qnamePair.getFirst();
 | |
|                 return true;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public Long getTypeQNameId()
 | |
|     {
 | |
|         return typeQNameId;
 | |
|     }
 | |
|     
 | |
|     /**
 | |
|      * @deprecated                      For persistence use only
 | |
|      */
 | |
|     public void setTypeQNameId(Long typeQNameId)
 | |
|     {
 | |
|         this.typeQNameId = typeQNameId;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Helper method to set all values associated with the
 | |
|      * {@link #setChildNodeName(String) child node name}.
 | |
|      * 
 | |
|      * @param dictionaryService         the service that determines how the CRC values are generated.
 | |
|      *                                  If this is <tt>null</tt> then the CRC values are generated
 | |
|      *                                  assuming that positive enforcement of the name constraint is
 | |
|      *                                  required.
 | |
|      * @param childNodeName             the child node name
 | |
|      */
 | |
|     public void setChildNodeNameAll(
 | |
|             DictionaryService dictionaryService,
 | |
|             QName typeQName,
 | |
|             String childNodeName)
 | |
|     {
 | |
|         ParameterCheck.mandatory("childNodeName", childNodeName);
 | |
|         
 | |
|         if (dictionaryService != null)
 | |
|         {
 | |
|             ParameterCheck.mandatory("typeQName", typeQName);
 | |
|             
 | |
|             Pair<String, Long> childNameUnique = ChildAssocEntity.getChildNameUnique(
 | |
|                     dictionaryService,
 | |
|                     typeQName,
 | |
|                     childNodeName);
 | |
|             this.childNodeName = childNameUnique.getFirst();
 | |
|             this.childNodeNameCrc = childNameUnique.getSecond();
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             String childNameNewLower = childNodeName.toLowerCase();
 | |
|             this.childNodeName = ChildAssocEntity.getChildNodeNameShort(childNameNewLower);
 | |
|             this.childNodeNameCrc = ChildAssocEntity.getChildNodeNameCrc(childNameNewLower);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     public Long getChildNodeNameCrc()
 | |
|     {
 | |
|         return childNodeNameCrc;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @deprecated                      For persistence use
 | |
|      */
 | |
|     public void setChildNodeNameCrc(Long childNodeNameCrc)
 | |
|     {
 | |
|         this.childNodeNameCrc = childNodeNameCrc;
 | |
|     }
 | |
| 
 | |
|     public String getChildNodeName()
 | |
|     {
 | |
|         return childNodeName;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @deprecated                      For persistence use
 | |
|      */
 | |
|     public void setChildNodeName(String childNodeName)
 | |
|     {
 | |
|         this.childNodeName = childNodeName;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set all required fields associated with the patch <code>QName</code>.
 | |
|      * 
 | |
|      * @param forUpdate                 <tt>true</tt> if the entity is going to be used for a
 | |
|      *                                  data update i.e. the <code>QName</code> <b>must</b> exist.
 | |
|      * @return                          Returns <tt>true</tt> if the <code>QName</code> namespace
 | |
|      *                                  exists.
 | |
|      */
 | |
|     public boolean setQNameAll(QNameDAO qnameDAO, QName qname, boolean forUpdate)
 | |
|     {
 | |
|         String assocQNameNamespace = qname.getNamespaceURI();
 | |
|         String assocQNameLocalName = qname.getLocalName();
 | |
|         Long assocQNameNamespaceId = null;
 | |
|         if (forUpdate)
 | |
|         {
 | |
|             assocQNameNamespaceId = qnameDAO.getOrCreateNamespace(assocQNameNamespace).getFirst();
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             Pair<Long, String> nsPair = qnameDAO.getNamespace(assocQNameNamespace);
 | |
|             if (nsPair == null)
 | |
|             {
 | |
|                 // We can't set anything
 | |
|                 return false;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 assocQNameNamespaceId = nsPair.getFirst();
 | |
|             }
 | |
|         }
 | |
|         Long assocQNameCrc = getQNameCrc(qname);
 | |
| 
 | |
|         this.qnameNamespaceId = assocQNameNamespaceId;
 | |
|         this.qnameLocalName = assocQNameLocalName;
 | |
|         this.qnameCrc = assocQNameCrc;
 | |
|         
 | |
|         // All set correctly
 | |
|         return true;
 | |
|     }
 | |
|     
 | |
|     public Long getQnameNamespaceId()
 | |
|     {
 | |
|         return qnameNamespaceId;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @deprecated                      For persistence use
 | |
|      */
 | |
|     public void setQnameNamespaceId(Long qnameNamespaceId)
 | |
|     {
 | |
|         this.qnameNamespaceId = qnameNamespaceId;
 | |
|     }
 | |
| 
 | |
|     public String getQnameLocalName()
 | |
|     {
 | |
|         return qnameLocalName;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @deprecated                      For persistence use
 | |
|      */
 | |
|     public void setQnameLocalName(String qnameLocalName)
 | |
|     {
 | |
|         this.qnameLocalName = qnameLocalName;
 | |
|     }
 | |
| 
 | |
|     public Long getQnameCrc()
 | |
|     {
 | |
|         return qnameCrc;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @deprecated                      For persistence use
 | |
|      */
 | |
|     public void setQnameCrc(Long qnameCrc)
 | |
|     {
 | |
|         this.qnameCrc = qnameCrc;
 | |
|     }
 | |
| 
 | |
|     public Boolean isPrimary()
 | |
|     {
 | |
|         return isPrimary;
 | |
|     }
 | |
| 
 | |
|     public void setPrimary(Boolean isPrimary)
 | |
|     {
 | |
|         this.isPrimary = isPrimary;
 | |
|     }
 | |
| 
 | |
|     public int getAssocIndex()
 | |
|     {
 | |
|         return assocIndex;
 | |
|     }
 | |
| 
 | |
|     public void setAssocIndex(int assocIndex)
 | |
|     {
 | |
|         this.assocIndex = assocIndex;
 | |
|     }
 | |
| 
 | |
|     public List<Long> getTypeQNameIds()
 | |
|     {
 | |
|         return typeQNameIds;
 | |
|     }
 | |
| 
 | |
|     public void setTypeQNameIds(List<Long> typeQNameIds)
 | |
|     {
 | |
|         this.typeQNameIds = typeQNameIds;
 | |
|     }
 | |
| 
 | |
|     public List<Long> getChildNodeNameCrcs()
 | |
|     {
 | |
|         return childNodeNameCrcs;
 | |
|     }
 | |
| 
 | |
|     public void setChildNodeNameCrcs(List<Long> childNodeNameCrcs)
 | |
|     {
 | |
|         this.childNodeNameCrcs = childNodeNameCrcs;
 | |
|     }
 | |
| 
 | |
|     public List<Long> getChildNodeTypeQNameIds()
 | |
|     {
 | |
|         return childNodeTypeQNameIds;
 | |
|     }
 | |
| 
 | |
|     public void setChildNodeTypeQNameIds(List<Long> childNodeTypeQNameIds)
 | |
|     {
 | |
|         this.childNodeTypeQNameIds = childNodeTypeQNameIds;
 | |
|     }
 | |
| 
 | |
|     public Boolean getSameStore()
 | |
|     {
 | |
|         return sameStore;
 | |
|     }
 | |
| 
 | |
|     public void setSameStore(Boolean sameStore)
 | |
|     {
 | |
|         this.sameStore = sameStore;
 | |
|     }
 | |
| 
 | |
|     public boolean isOrdered()
 | |
|     {
 | |
|         return ordered;
 | |
|     }
 | |
| 
 | |
|     public void setOrdered(boolean ordered)
 | |
|     {
 | |
|         this.ordered = ordered;
 | |
|     }
 | |
| }
 |