Fixes for supporting full repository export/import.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2625 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2006-04-05 19:14:20 +00:00
parent 9b22810956
commit 166de93b48
10 changed files with 175 additions and 44 deletions

View File

@@ -228,7 +228,7 @@ public class RoutingContentService implements ContentService
// Fire the content update policy
Set<QName> types = new HashSet<QName>(this.nodeService.getAspects(nodeRef));
types.add(this.nodeService.getType(nodeRef));
OnContentUpdatePolicy policy = this.onContentUpdateDelegate.get(types);
OnContentUpdatePolicy policy = this.onContentUpdateDelegate.get(nodeRef, types);
policy.onContentUpdate(nodeRef, newContent);
}
}
@@ -294,7 +294,7 @@ public class RoutingContentService implements ContentService
// Fire the content update policy
Set<QName> types = new HashSet<QName>(this.nodeService.getAspects(nodeRef));
types.add(this.nodeService.getType(nodeRef));
OnContentReadPolicy policy = this.onContentReadDelegate.get(types);
OnContentReadPolicy policy = this.onContentReadDelegate.get(nodeRef, types);
policy.onContentRead(nodeRef);
}

View File

@@ -53,6 +53,7 @@ import org.alfresco.service.cmr.view.ExporterException;
import org.alfresco.service.cmr.view.ExporterService;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.cmr.view.ReferenceType;
import org.alfresco.service.descriptor.DescriptorService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
@@ -158,7 +159,7 @@ public class ExporterComponent
ParameterCheck.mandatory("View Writer", viewWriter);
// Construct a basic XML Exporter
Exporter xmlExporter = createXMLExporter(viewWriter);
Exporter xmlExporter = createXMLExporter(viewWriter, parameters.getReferenceType());
// Export
exportView(xmlExporter, parameters, progress);
@@ -174,7 +175,7 @@ public class ExporterComponent
// create exporter around export handler
exportHandler.startExport();
OutputStream dataFile = exportHandler.createDataStream();
Exporter xmlExporter = createXMLExporter(dataFile);
Exporter xmlExporter = createXMLExporter(dataFile, parameters.getReferenceType());
URLExporter urlExporter = new URLExporter(xmlExporter, exportHandler);
// export
@@ -201,9 +202,10 @@ public class ExporterComponent
* output stream in xml format.
*
* @param viewWriter the output stream to write to
* @param referenceType the format of references to export
* @return the xml exporter
*/
private Exporter createXMLExporter(OutputStream viewWriter)
private Exporter createXMLExporter(OutputStream viewWriter, ReferenceType referenceType)
{
// Define output format
OutputFormat format = OutputFormat.createPrettyPrint();
@@ -215,12 +217,18 @@ public class ExporterComponent
try
{
XMLWriter writer = new XMLWriter(viewWriter, format);
return new ViewXMLExporter(namespaceService, nodeService, searchService, dictionaryService, permissionService, writer);
ViewXMLExporter exporter = new ViewXMLExporter(namespaceService, nodeService, searchService, dictionaryService, permissionService, writer);
exporter.setReferenceType(referenceType);
return exporter;
}
catch (UnsupportedEncodingException e)
{
throw new ExporterException("Failed to create XML Writer for export", e);
}
catch (Exception e)
{
throw new ExporterException("Failed to create XML Writer for export", e);
}
}
@@ -254,12 +262,12 @@ public class ExporterComponent
// determine if root repository node
NodeRef nodeRef = context.getExportOf();
boolean rootNode = nodeService.getRootNode(nodeRef.getStoreRef()).equals(nodeRef);
if (parameters.isCrawlSelf() && !rootNode)
if (parameters.isCrawlSelf())
{
// export root node of specified export location
walkStartNamespaces(parameters, exporter);
walkNode(nodeRef, parameters, exporter);
boolean rootNode = nodeService.getRootNode(nodeRef.getStoreRef()).equals(nodeRef);
walkNode(nodeRef, parameters, exporter, rootNode);
walkEndNamespaces(parameters, exporter);
}
else if (parameters.isCrawlChildNodes())
@@ -269,7 +277,7 @@ public class ExporterComponent
for (ChildAssociationRef childAssoc : childAssocs)
{
walkStartNamespaces(parameters, exporter);
walkNode(childAssoc.getChildRef(), parameters, exporter);
walkNode(childAssoc.getChildRef(), parameters, exporter, false);
walkEndNamespaces(parameters, exporter);
}
}
@@ -335,7 +343,7 @@ public class ExporterComponent
*
* @param nodeRef the node to navigate
*/
private void walkNode(NodeRef nodeRef, ExporterCrawlerParameters parameters, Exporter exporter)
private void walkNode(NodeRef nodeRef, ExporterCrawlerParameters parameters, Exporter exporter, boolean exportAsRef)
{
// Export node (but only if it's not excluded from export)
QName type = nodeService.getType(nodeRef);
@@ -344,7 +352,15 @@ public class ExporterComponent
return;
}
exporter.startNode(nodeRef);
// export node as reference to node, or as the actual node
if (exportAsRef)
{
exporter.startReference(nodeRef, null);
}
else
{
exporter.startNode(nodeRef);
}
// Export node aspects
exporter.startAspects(nodeRef);
@@ -361,7 +377,7 @@ public class ExporterComponent
// Export node permissions
AccessStatus readPermission = permissionService.hasPermission(nodeRef, PermissionService.READ_PERMISSIONS);
if (readPermission.equals(AccessStatus.ALLOWED))
if (authenticationService.isCurrentUserTheSystemUser() || readPermission.equals(AccessStatus.ALLOWED))
{
Set<AccessPermission> permissions = permissionService.getAllSetPermissions(nodeRef);
boolean inheritPermissions = permissionService.getInheritParentPermissions(nodeRef);
@@ -442,7 +458,7 @@ public class ExporterComponent
}
if (!isExcludedURI(parameters.getExcludeNamespaceURIs(), childAssoc.getQName().getNamespaceURI()))
{
walkNode(childAssoc.getChildRef(), parameters, exporter);
walkNode(childAssoc.getChildRef(), parameters, exporter, false);
}
if (i == childAssocs.size() - 1 || childAssocs.get(i + 1).getTypeQName().equals(childAssocType) == false)
{
@@ -463,7 +479,15 @@ public class ExporterComponent
}
// Signal end of node
exporter.endNode(nodeRef);
// export node as reference to node, or as the actual node
if (exportAsRef)
{
exporter.endReference(nodeRef);
}
else
{
exporter.endNode(nodeRef);
}
}
/**

View File

@@ -43,6 +43,7 @@ import org.alfresco.service.cmr.view.ExporterCrawlerParameters;
import org.alfresco.service.cmr.view.ExporterException;
import org.alfresco.service.cmr.view.ExporterService;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.cmr.view.ReferenceType;
import org.alfresco.service.cmr.view.RepositoryExporterService;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
@@ -276,6 +277,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService
parameters.setCrawlAssociations(true);
parameters.setCrawlNullProperties(true);
parameters.setExcludeNamespaceURIs(new String[] {});
parameters.setReferenceType(ReferenceType.NODEREF);
return parameters;
}
@@ -294,7 +296,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService
public FileExportHandle exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress)
{
// create a temporary file to hold the acp export
File tempFile = TempFileProvider.createTempFile("repoExp", "." + ACPExportPackageHandler.ACP_EXTENSION);
File tempFile = TempFileProvider.createTempFile("repoExp" + packageName, "." + ACPExportPackageHandler.ACP_EXTENSION);
// create acp export handler around the temp file
File dataFile = new File(packageName);
@@ -383,6 +385,7 @@ public class RepositoryExporterComponent implements RepositoryExporterService
*
* @author davidc
*/
@SuppressWarnings("unused")
private class RepositoryFileExporter implements ExportStore<RepositoryExportHandle>
{
private TempFileExporter tempFileExporter = new TempFileExporter();

View File

@@ -34,6 +34,7 @@ import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.view.Exporter;
import org.alfresco.service.cmr.view.ExporterContext;
import org.alfresco.service.cmr.view.ExporterException;
import org.alfresco.service.cmr.view.ReferenceType;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.xml.sax.ContentHandler;
@@ -72,6 +73,7 @@ import org.xml.sax.helpers.AttributesImpl;
private static final String INHERITPERMISSIONS_LOCALNAME = "inherit";
private static final String REFERENCE_LOCALNAME = "reference";
private static final String PATHREF_LOCALNAME = "pathref";
private static final String NODEREF_LOCALNAME = "noderef";
private static QName VIEW_QNAME;
private static QName VALUES_QNAME;
private static QName VALUE_QNAME;
@@ -94,6 +96,7 @@ import org.xml.sax.helpers.AttributesImpl;
private static QName INHERITPERMISSIONS_QNAME;
private static QName REFERENCE_QNAME;
private static QName PATHREF_QNAME;
private static QName NODEREF_QNAME;
private static final AttributesImpl EMPTY_ATTRIBUTES = new AttributesImpl();
// Service dependencies
@@ -107,6 +110,10 @@ import org.xml.sax.helpers.AttributesImpl;
private ContentHandler contentHandler;
private ExporterContext context;
// Configuration
private ReferenceType referenceType;
/**
* Construct
@@ -147,6 +154,18 @@ import org.xml.sax.helpers.AttributesImpl;
INHERITPERMISSIONS_QNAME = QName.createQName(NamespaceService.REPOSITORY_VIEW_PREFIX, INHERITPERMISSIONS_LOCALNAME, namespaceService);
REFERENCE_QNAME = QName.createQName(NamespaceService.REPOSITORY_VIEW_PREFIX, REFERENCE_LOCALNAME, namespaceService);
PATHREF_QNAME = QName.createQName(NamespaceService.REPOSITORY_VIEW_PREFIX, PATHREF_LOCALNAME, namespaceService);
NODEREF_QNAME = QName.createQName(NamespaceService.REPOSITORY_VIEW_PREFIX, NODEREF_LOCALNAME, namespaceService);
}
/**
* Set Reference Type to export with
*
* @param referenceType reference type to export
*/
public void setReferenceType(ReferenceType referenceType)
{
this.referenceType = referenceType;
}
@@ -518,7 +537,7 @@ import org.xml.sax.helpers.AttributesImpl;
NodeRef valueNodeRef = (NodeRef)value;
if (nodeRef.getStoreRef().equals(valueNodeRef.getStoreRef()))
{
Path nodeRefPath = createRelativePath(context.getExportOf(), nodeRef, valueNodeRef);
Path nodeRefPath = createPath(context.getExportOf(), nodeRef, valueNodeRef);
value = (nodeRefPath == null) ? null : nodeRefPath.toPrefixString(namespaceService);
}
}
@@ -632,9 +651,24 @@ import org.xml.sax.helpers.AttributesImpl;
{
try
{
Path path = createRelativePath(context.getExportParent(), context.getExportParent(), nodeRef);
// determine format of reference e.g. node or path based
ReferenceType referenceFormat = referenceType;
if (nodeRef.equals(nodeService.getRootNode(nodeRef.getStoreRef())))
{
referenceFormat = ReferenceType.PATHREF;
}
// output reference
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute(NamespaceService.REPOSITORY_VIEW_1_0_URI, PATHREF_LOCALNAME, PATHREF_QNAME.toPrefixString(), null, path.toPrefixString(namespaceService));
if (referenceFormat.equals(ReferenceType.PATHREF))
{
Path path = createPath(context.getExportParent(), context.getExportParent(), nodeRef);
attrs.addAttribute(NamespaceService.REPOSITORY_VIEW_1_0_URI, PATHREF_LOCALNAME, PATHREF_QNAME.toPrefixString(), null, path.toPrefixString(namespaceService));
}
else
{
attrs.addAttribute(NamespaceService.REPOSITORY_VIEW_1_0_URI, NODEREF_LOCALNAME, NODEREF_QNAME.toPrefixString(), null, nodeRef.toString());
}
if (childName != null)
{
attrs.addAttribute(NamespaceService.REPOSITORY_VIEW_1_0_URI, CHILDNAME_LOCALNAME, CHILDNAME_QNAME.toPrefixString(), null, childName.toPrefixString(namespaceService));
@@ -704,7 +738,7 @@ import org.xml.sax.helpers.AttributesImpl;
* @param toRef to reference
* @return path
*/
private Path createRelativePath(NodeRef rootRef, NodeRef fromRef, NodeRef toRef)
private Path createPath(NodeRef rootRef, NodeRef fromRef, NodeRef toRef)
{
// Check that item exists first
if (!nodeService.exists(toRef))
@@ -713,6 +747,14 @@ import org.xml.sax.helpers.AttributesImpl;
return null;
}
// Check whether item is the root node of the store
// If so, always return absolute path
if (toRef.equals(nodeService.getRootNode(toRef.getStoreRef())))
{
return nodeService.getPath(toRef);
}
// construct relative path
Path rootPath = createIndexedPath(rootRef, nodeService.getPath(rootRef));
Path fromPath = createIndexedPath(fromRef, nodeService.getPath(fromRef));
Path toPath = createIndexedPath(toRef, nodeService.getPath(toRef));

View File

@@ -74,11 +74,12 @@ public interface ImportNode
public Map<QName,Serializable> getProperties();
/**
* Gets all property datatypes for the node
* Gets the property data type
*
* @return the property datatypes
* @param propertyName name of property
* @return data type of named property
*/
public Map<QName,DataTypeDefinition> getPropertyDatatypes();
public DataTypeDefinition getPropertyDataType(QName propertyName);
/**
* @return the aspects of this node

View File

@@ -36,7 +36,6 @@ import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
@@ -548,8 +547,9 @@ public class ImporterComponent
// import content, if applicable
for (Map.Entry<QName,Serializable> property : context.getProperties().entrySet())
{
PropertyDefinition propertyDef = dictionaryService.getProperty(property.getKey());
if (propertyDef != null && propertyDef.getDataType().getName().equals(DataTypeDefinition.CONTENT))
// filter out content properties (they're imported later)
DataTypeDefinition valueDataType = context.getPropertyDataType(property.getKey());
if (valueDataType != null && valueDataType.getName().equals(DataTypeDefinition.CONTENT))
{
importContent(nodeRef, property.getKey(), (String)property.getValue());
}
@@ -627,10 +627,10 @@ public class ImporterComponent
private void importContent(NodeRef nodeRef, QName propertyName, String importContentData)
{
// bind import content data description
DataTypeDefinition dataTypeDef = dictionaryService.getDataType(DataTypeDefinition.CONTENT);
importContentData = bindPlaceHolder(importContentData, binding);
if (importContentData != null && importContentData.length() > 0)
{
DataTypeDefinition dataTypeDef = dictionaryService.getDataType(DataTypeDefinition.CONTENT);
ContentData contentData = (ContentData)DefaultTypeConverter.INSTANCE.convert(dataTypeDef, importContentData);
String contentUrl = contentData.getContentUrl();
if (contentUrl != null && contentUrl.length() > 0)
@@ -898,23 +898,11 @@ public class ImporterComponent
private Map<QName, Serializable> bindProperties(ImportNode context)
{
Map<QName, Serializable> properties = context.getProperties();
Map<QName, DataTypeDefinition> datatypes = context.getPropertyDatatypes();
Map<QName, Serializable> boundProperties = new HashMap<QName, Serializable>(properties.size());
for (QName property : properties.keySet())
{
// get property value
Serializable value = properties.get(property);
// get property datatype
DataTypeDefinition valueDataType = datatypes.get(property);
if (valueDataType == null)
{
PropertyDefinition propDef = dictionaryService.getProperty(property);
if (propDef != null)
{
valueDataType = propDef.getDataType();
}
}
DataTypeDefinition valueDataType = context.getPropertyDataType(property);
// filter out content properties (they're imported later)
if (valueDataType != null && valueDataType.getName().equals(DataTypeDefinition.CONTENT))
@@ -922,6 +910,9 @@ public class ImporterComponent
continue;
}
// get property value
Serializable value = properties.get(property);
// bind property value to configuration and convert to appropriate type
if (value instanceof Collection)
{

View File

@@ -61,6 +61,7 @@ public class ImporterComponentTest extends BaseSpringTest
super.onTearDownInTransaction();
}
public void testImport()
throws Exception
{

View File

@@ -246,7 +246,7 @@ public class NodeContext extends ElementContext
PropertyDefinition propDef = getDictionaryService().getProperty(property);
// Process Alfresco UUID
if (propDef != null && propDef.getName().equals(ContentModel.PROP_NODE_UUID))
if (uuid == null && propDef != null && propDef.getName().equals(ContentModel.PROP_NODE_UUID))
{
uuid = value;
}
@@ -311,6 +311,25 @@ public class NodeContext extends ElementContext
return nodeProperties;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportNode#getPropertyDataType(org.alfresco.service.namespace.QName)
*/
public DataTypeDefinition getPropertyDataType(QName propertyName)
{
// get property datatype
DataTypeDefinition valueDataType = propertyDatatypes.get(propertyName);
if (valueDataType == null)
{
PropertyDefinition propDef = getDictionaryService().getProperty(propertyName);
if (propDef != null)
{
valueDataType = propDef.getDataType();
}
}
return valueDataType;
}
/**
* Adds an aspect to the node
*

View File

@@ -35,6 +35,7 @@ public class ExporterCrawlerParameters
private boolean crawlAssociations = true;
private boolean crawlContent = true;
private boolean crawlNullProperties = true;
private ReferenceType referenceType = ReferenceType.PATHREF;
private String[] excludeNamespaceURIs = new String[] { NamespaceService.REPOSITORY_VIEW_1_0_URI };
@@ -178,4 +179,24 @@ public class ExporterCrawlerParameters
this.exportFrom = exportFrom;
}
/**
* Gets the format of exported references
*
* @return reference type
*/
public ReferenceType getReferenceType()
{
return referenceType;
}
/**
* Sets the format of exported references (child and association references)
*
* @param reference type
*/
public void setReferenceType(ReferenceType referenceType)
{
this.referenceType = referenceType;
}
}

View File

@@ -0,0 +1,29 @@
/*
* 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.view;
/**
* Enumeration of various types of Reference
*
* @author davidc
*/
public enum ReferenceType
{
NODEREF,
PATHREF
}