mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Big honkin' merge from head. Sheesh!
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@3617 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -33,9 +33,7 @@ public class AssociationExistsException extends RuntimeException
|
||||
private QName qname;
|
||||
|
||||
/**
|
||||
* @param sourceRef the source of the association
|
||||
* @param targetRef the target of the association
|
||||
* @param qname the qualified name of the association
|
||||
* @see #AssociationExistsException(NodeRef, NodeRef, QName, Throwable)
|
||||
*/
|
||||
public AssociationExistsException(NodeRef sourceRef, NodeRef targetRef, QName qname)
|
||||
{
|
||||
@@ -45,6 +43,20 @@ public class AssociationExistsException extends RuntimeException
|
||||
this.qname = qname;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sourceRef the source of the association
|
||||
* @param targetRef the target of the association
|
||||
* @param qname the qualified name of the association
|
||||
* @param cause a causal exception
|
||||
*/
|
||||
public AssociationExistsException(NodeRef sourceRef, NodeRef targetRef, QName qname, Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
this.sourceRef = sourceRef;
|
||||
this.targetRef = targetRef;
|
||||
this.qname = qname;
|
||||
}
|
||||
|
||||
public NodeRef getSourceRef()
|
||||
{
|
||||
return sourceRef;
|
||||
|
@@ -25,6 +25,13 @@ import org.alfresco.service.transaction.TransactionService;
|
||||
*/
|
||||
public interface ContentAccessor
|
||||
{
|
||||
/**
|
||||
* Gets the open/close state of the underlying IO Channel.
|
||||
*
|
||||
* @return Returns true if the underlying IO Channel is open
|
||||
*/
|
||||
public boolean isChannelOpen();
|
||||
|
||||
/**
|
||||
* Use this method to register any interest in events against underlying
|
||||
* content streams.
|
||||
|
@@ -126,6 +126,14 @@ public interface ContentService
|
||||
@Auditable(parameters = {"sourceMimetype", "targetMimetype"})
|
||||
public ContentTransformer getTransformer(String sourceMimetype, String targetMimetype);
|
||||
|
||||
/**
|
||||
* Fetch the transformer that is capable of transforming image content.
|
||||
*
|
||||
* @return Returns a transformer that can be used, or null if one was not available
|
||||
*/
|
||||
@Auditable
|
||||
public ContentTransformer getImageTransformer();
|
||||
|
||||
/**
|
||||
* Returns whether a transformer exists that can read the content from
|
||||
* the reader and write the content back out to the writer.
|
||||
|
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2005 Alfresco, Inc.
|
||||
*
|
||||
* Licensed under the Mozilla Public License version 1.1
|
||||
* with a permitted attribution clause. You may obtain a
|
||||
* copy of the License at
|
||||
*
|
||||
* http://www.alfresco.org/legal/license.txt
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
* either express or implied. See the License for the specific
|
||||
* language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
package org.alfresco.service.cmr.repository;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown when a child node <b>cm:name</b> property violates the data dictionary
|
||||
* <b>duplicate</b> child association constraint.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class DuplicateChildNodeNameException extends RuntimeException
|
||||
{
|
||||
private static final long serialVersionUID = 5143099335847200453L;
|
||||
|
||||
private static final String ERR_DUPLICATE_NAME = "system.err.duplicate_name";
|
||||
|
||||
private NodeRef parentNodeRef;
|
||||
private QName assocTypeQName;
|
||||
private String name;
|
||||
|
||||
public DuplicateChildNodeNameException(NodeRef parentNodeRef, QName assocTypeQName, String name)
|
||||
{
|
||||
super(I18NUtil.getMessage(ERR_DUPLICATE_NAME, name));
|
||||
this.parentNodeRef = parentNodeRef;
|
||||
this.assocTypeQName = assocTypeQName;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public NodeRef getParentNodeRef()
|
||||
{
|
||||
return parentNodeRef;
|
||||
}
|
||||
|
||||
public QName getAssocTypeQName()
|
||||
{
|
||||
return assocTypeQName;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
@@ -417,6 +417,21 @@ public interface NodeService
|
||||
QNamePattern qnamePattern)
|
||||
throws InvalidNodeRefException;
|
||||
|
||||
/**
|
||||
* Get the node with the given name within the context of the parent node. The name
|
||||
* is case-insensitive as Alfresco has to support case-insensitive clients as standard.
|
||||
*
|
||||
* @param nodeRef the parent node - usuall a <b>container</b>
|
||||
* @param assocTypeQName the type of the association
|
||||
* @param childName the name of the node as per the property <b>cm:name</b>
|
||||
* @return Returns the child node or null if not found
|
||||
*/
|
||||
@Auditable(key = Auditable.Key.ARG_0 ,parameters = {"nodeRef", "assocTypeQName", "childName"})
|
||||
public NodeRef getChildByName(
|
||||
NodeRef nodeRef,
|
||||
QName assocTypeQName,
|
||||
String childName);
|
||||
|
||||
/**
|
||||
* Fetches the primary parent-child relationship.
|
||||
* <p>
|
||||
|
@@ -30,6 +30,7 @@ import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||
import org.alfresco.repo.template.LuceneSearchResultsMap;
|
||||
import org.alfresco.repo.template.NamePathResultsMap;
|
||||
import org.alfresco.repo.template.NodeSearchResultsMap;
|
||||
import org.alfresco.repo.template.SavedSearchResultsMap;
|
||||
import org.alfresco.repo.template.XPathResultsMap;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
@@ -96,6 +97,9 @@ public final class TemplateNode implements Serializable
|
||||
private ChildAssociationRef primaryParentAssoc = null;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Construction
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@@ -123,6 +127,10 @@ public final class TemplateNode implements Serializable
|
||||
this.properties = new QNameMap<String, Object>(this.services.getNamespaceService());
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Node API
|
||||
|
||||
/**
|
||||
* @return The GUID for the node
|
||||
*/
|
||||
@@ -200,41 +208,6 @@ public final class TemplateNode implements Serializable
|
||||
return this.children;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map capable of returning the TemplateNode at the specified Path as a child of this node.
|
||||
*/
|
||||
public Map getChildByNamePath()
|
||||
{
|
||||
return new NamePathResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map capable of returning a List of TemplateNode objects from an XPath query
|
||||
* as children of this node.
|
||||
*/
|
||||
public Map getChildrenByXPath()
|
||||
{
|
||||
return new XPathResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Saved Search
|
||||
* object. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
||||
*/
|
||||
public Map getChildrenBySavedSearch()
|
||||
{
|
||||
return new SavedSearchResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Lucene search
|
||||
* string. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
||||
*/
|
||||
public Map getChildrenByLuceneSearch()
|
||||
{
|
||||
return new LuceneSearchResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The associations for this Node. As a Map of assoc name to a List of TemplateNodes.
|
||||
*/
|
||||
@@ -367,6 +340,142 @@ public final class TemplateNode implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the node is currently locked
|
||||
*/
|
||||
public boolean getIsLocked()
|
||||
{
|
||||
boolean locked = false;
|
||||
|
||||
if (getAspects().contains(ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
LockStatus lockStatus = this.services.getLockService().getLockStatus(this.nodeRef);
|
||||
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
return locked;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the parent node
|
||||
*/
|
||||
public TemplateNode getParent()
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
NodeRef parentRef = this.services.getNodeService().getPrimaryParent(nodeRef).getParentRef();
|
||||
// handle root node (no parent!)
|
||||
if (parentRef != null)
|
||||
{
|
||||
parent = new TemplateNode(parentRef, this.services, this.imageResolver);
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the primary parent association so we can access the association QName and association type QName.
|
||||
*/
|
||||
public ChildAssociationRef getPrimaryParentAssoc()
|
||||
{
|
||||
if (primaryParentAssoc == null)
|
||||
{
|
||||
primaryParentAssoc = this.services.getNodeService().getPrimaryParent(nodeRef);
|
||||
}
|
||||
return primaryParentAssoc;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Content API
|
||||
|
||||
/**
|
||||
* @return the content String for this node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public String getContent()
|
||||
{
|
||||
ContentService contentService = this.services.getContentService();
|
||||
ContentReader reader = contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
|
||||
return (reader != null && reader.exists()) ? reader.getContentString() : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @return For a content document, this method returns the URL to the content stream for
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
* <p>
|
||||
* For a container node, this method return the URL to browse to the folder in the web-client
|
||||
*/
|
||||
public String getUrl()
|
||||
{
|
||||
if (getIsDocument() == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
return MessageFormat.format(CONTENT_DEFAULT_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") } );
|
||||
}
|
||||
catch (UnsupportedEncodingException err)
|
||||
{
|
||||
throw new TemplateException("Failed to encode content URL for node: " + nodeRef, err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(FOLDER_BROWSE_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId() } );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The mimetype encoding for content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public String getMimetype()
|
||||
{
|
||||
if (mimetype == null)
|
||||
{
|
||||
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
mimetype = content.getMimetype();
|
||||
}
|
||||
}
|
||||
|
||||
return mimetype;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The size in bytes of the content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public long getSize()
|
||||
{
|
||||
if (size == null)
|
||||
{
|
||||
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
size = content.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
return size != null ? size.longValue() : 0L;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Node Helper API
|
||||
|
||||
/**
|
||||
* @return FreeMarker NodeModel for the XML content of this node, or null if no parsable XML found
|
||||
*/
|
||||
@@ -457,24 +566,9 @@ public final class TemplateNode implements Serializable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the node is currently locked
|
||||
*/
|
||||
public boolean getIsLocked()
|
||||
{
|
||||
boolean locked = false;
|
||||
|
||||
if (getAspects().contains(ContentModel.ASPECT_LOCKABLE))
|
||||
{
|
||||
LockStatus lockStatus = this.services.getLockService().getLockStatus(this.nodeRef);
|
||||
if (lockStatus == LockStatus.LOCKED || lockStatus == LockStatus.LOCK_OWNER)
|
||||
{
|
||||
locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
return locked;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Security API
|
||||
|
||||
/**
|
||||
* @return List of permissions applied to this Node.
|
||||
@@ -510,114 +604,56 @@ public final class TemplateNode implements Serializable
|
||||
return this.services.getPermissionService().getInheritParentPermissions(this.nodeRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the parent node
|
||||
*/
|
||||
public TemplateNode getParent()
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
NodeRef parentRef = this.services.getNodeService().getPrimaryParent(nodeRef).getParentRef();
|
||||
// handle root node (no parent!)
|
||||
if (parentRef != null)
|
||||
{
|
||||
parent = new TemplateNode(parentRef, this.services, this.imageResolver);
|
||||
}
|
||||
}
|
||||
|
||||
return parent;
|
||||
// ------------------------------------------------------------------------------
|
||||
// Search API
|
||||
|
||||
/**
|
||||
* @return A map capable of returning the TemplateNode at the specified Path as a child of this node.
|
||||
*/
|
||||
public Map getChildByNamePath()
|
||||
{
|
||||
return new NamePathResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the primary parent association so we can access the association QName and association type QName.
|
||||
* @return A map capable of returning a List of TemplateNode objects from an XPath query
|
||||
* as children of this node.
|
||||
*/
|
||||
public ChildAssociationRef getPrimaryParentAssoc()
|
||||
public Map getChildrenByXPath()
|
||||
{
|
||||
if (primaryParentAssoc == null)
|
||||
{
|
||||
primaryParentAssoc = this.services.getNodeService().getPrimaryParent(nodeRef);
|
||||
}
|
||||
return primaryParentAssoc;
|
||||
return new XPathResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the content String for this node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Saved Search
|
||||
* object. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
||||
*/
|
||||
public String getContent()
|
||||
public Map getChildrenBySavedSearch()
|
||||
{
|
||||
ContentService contentService = this.services.getContentService();
|
||||
ContentReader reader = contentService.getReader(this.nodeRef, ContentModel.PROP_CONTENT);
|
||||
return (reader != null && reader.exists()) ? reader.getContentString() : "";
|
||||
return new SavedSearchResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return For a content document, this method returns the URL to the content stream for
|
||||
* the default content property (@see ContentModel.PROP_CONTENT)
|
||||
* <p>
|
||||
* For a container node, this method return the URL to browse to the folder in the web-client
|
||||
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Lucene search
|
||||
* string. The Saved Search is executed and the resulting nodes supplied as a sequence.
|
||||
*/
|
||||
public String getUrl()
|
||||
public Map getChildrenByLuceneSearch()
|
||||
{
|
||||
if (getIsDocument() == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
return MessageFormat.format(CONTENT_DEFAULT_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId(),
|
||||
StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") } );
|
||||
}
|
||||
catch (UnsupportedEncodingException err)
|
||||
{
|
||||
throw new TemplateException("Failed to encode content URL for node: " + nodeRef, err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return MessageFormat.format(FOLDER_BROWSE_URL, new Object[] {
|
||||
nodeRef.getStoreRef().getProtocol(),
|
||||
nodeRef.getStoreRef().getIdentifier(),
|
||||
nodeRef.getId() } );
|
||||
}
|
||||
return new LuceneSearchResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The mimetype encoding for content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
* @return A map capable of returning a TemplateNode for a single specified NodeRef reference.
|
||||
*/
|
||||
public String getMimetype()
|
||||
public Map getNodeByReference()
|
||||
{
|
||||
if (mimetype == null)
|
||||
{
|
||||
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
mimetype = content.getMimetype();
|
||||
}
|
||||
}
|
||||
|
||||
return mimetype;
|
||||
return new NodeSearchResultsMap(this, this.services);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The size in bytes of the content attached to the node from the default content property
|
||||
* (@see ContentModel.PROP_CONTENT)
|
||||
*/
|
||||
public long getSize()
|
||||
{
|
||||
if (size == null)
|
||||
{
|
||||
TemplateContentData content = (TemplateContentData)this.getProperties().get(ContentModel.PROP_CONTENT);
|
||||
if (content != null)
|
||||
{
|
||||
size = content.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
return size != null ? size.longValue() : 0L;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Misc helpers
|
||||
|
||||
/**
|
||||
* @return the image resolver instance used by this node
|
||||
@@ -645,6 +681,9 @@ public final class TemplateNode implements Serializable
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Inner classes
|
||||
|
||||
/**
|
||||
* Inner class wrapping and providing access to a ContentData property
|
||||
*/
|
||||
|
Reference in New Issue
Block a user