package org.alfresco.repo.virtual.config; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.service.cmr.repository.NodeRef; /** * A String name or qname path expression that resolves to a {@link NodeRef}.
* The given name or qname path is relative to a {@link NodeRefContext} * repository location. The default context is set to * {@link CompanyHomeContext#COMPANY_HOME_CONTEXT_NAME}. Other contexts can be * set using their name with {@link #setContext(String)}.
* The set path is automatically detected and checked for consistency. */ public class NodeRefPathExpression implements NodeRefExpression { private static final String NAMESPACE_DELIMITER = ":"; private static final String PATH_DELIMITER = "/"; private Map contexts = new HashMap(); private NodeRefResolver resolver; private String context = CompanyHomeContext.COMPANY_HOME_CONTEXT_NAME; private String[] createNamePath; private String[] namePath; private String[] qNamePath; public NodeRefPathExpression(NodeRefResolver resolver, Map contexts) { this(resolver, contexts, CompanyHomeContext.COMPANY_HOME_CONTEXT_NAME, null); } public NodeRefPathExpression(NodeRefResolver resolver, Map contexts, String context, String path) { super(); this.resolver = resolver; this.contexts = contexts; this.context = context; setPath(path); } public void setContext(String context) { this.context = context; } public void setCreatedPathName(String createNamePath) { this.createNamePath = createNamePath.split(","); } /** * Path setter.
* The type of path is automatically detected and checked for consistency. * * @param path the string path to be resolved later * @throws AlfrescoRuntimeException if the given path is inconsistent (i.e. * a combination of qnames and names) */ public void setPath(String path) throws AlfrescoRuntimeException { String[] pathElements = splitAndNormalizePath(path); if (isQNamePath(pathElements)) { this.qNamePath = pathElements; } else if (isNamePath(pathElements)) { this.namePath = pathElements; } else { throw new AlfrescoRuntimeException("Invalid path format : " + path); } } private boolean isQNamePath(String[] pathElements) { for (int i = 0; i < pathElements.length; i++) { if (!pathElements[i].contains(NAMESPACE_DELIMITER)) { return false; } } return true; } private boolean isNamePath(String[] pathElements) { for (int i = 0; i < pathElements.length; i++) { if (pathElements[i].contains(NAMESPACE_DELIMITER)) { return false; } } return true; } public static String[] splitAndNormalizePath(String path) { if (path == null || path.trim().length() == 0) { return new String[] {}; } String[] splitPath = path.split(PATH_DELIMITER); // remove blank entries resulted from misplaced delimiters int shift = 0; for (int i = 0; i < splitPath.length; i++) { if (splitPath[i] == null || splitPath[i].trim().isEmpty()) { shift++; } else if (shift > 0) { splitPath[i - shift] = splitPath[i]; } } if (shift > 0) { String[] noBlanksSplitPath = new String[splitPath.length - shift]; if (noBlanksSplitPath.length > 0) { System.arraycopy(splitPath, 0, noBlanksSplitPath, 0, noBlanksSplitPath.length); } splitPath = noBlanksSplitPath; } return splitPath; } @Override public NodeRef resolve() { NodeRefContext theContext = contexts.get(context); if (this.namePath != null) { return theContext.resolveNamePath(this.namePath, resolver); } else { return theContext.resolveQNamePath(this.qNamePath, resolver); } } @Override public NodeRef resolve(boolean createIfNotFound) { NodeRef nodeRef = resolve(); if (nodeRef == null && createIfNotFound) { NodeRefContext theContext = contexts.get(context); if (this.namePath != null) { return theContext.createNamePath(this.namePath, resolver); } else { return theContext.createQNamePath(this.qNamePath, this.createNamePath, resolver); } } return nodeRef; } @Override public String toString() { StringBuilder pathString = new StringBuilder(); pathString.append("<"); pathString.append(this.context); pathString.append(">/"); if (this.namePath != null) { pathString.append(Arrays.toString(this.namePath)); } if (this.qNamePath != null) { pathString.append(Arrays.toString(this.qNamePath)); } return ""; } }