mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Full Repository Export / Import Support - first checkpoint
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2591 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.repo.action.executer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.action.ParameterDefinitionImpl;
|
||||
import org.alfresco.service.cmr.action.Action;
|
||||
import org.alfresco.service.cmr.action.ParameterDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.view.RepositoryExporterService;
|
||||
|
||||
/**
|
||||
* Repository Exporter action executor
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class RepositoryExporterActionExecuter extends ActionExecuterAbstractBase
|
||||
{
|
||||
public static final String NAME = "repository-export";
|
||||
public static final String PARAM_PACKAGE_NAME = "package-name";
|
||||
public static final String PARAM_DESTINATION_FOLDER = "destination";
|
||||
|
||||
/**
|
||||
* The exporter service
|
||||
*/
|
||||
private RepositoryExporterService exporterService;
|
||||
|
||||
/**
|
||||
* Sets the ExporterService to use
|
||||
*
|
||||
* @param exporterService The ExporterService
|
||||
*/
|
||||
public void setRepositoryExporterService(RepositoryExporterService exporterService)
|
||||
{
|
||||
this.exporterService = exporterService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.action.executer.ActionExecuter#execute(org.alfresco.repo.ref.NodeRef, org.alfresco.repo.ref.NodeRef)
|
||||
*/
|
||||
public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef)
|
||||
{
|
||||
String packageName = (String)ruleAction.getParameterValue(PARAM_PACKAGE_NAME);
|
||||
NodeRef repoDestination = (NodeRef)ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER);
|
||||
exporterService.export(repoDestination, packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.action.ParameterizedItemAbstractBase#addParameterDefintions(java.util.List)
|
||||
*/
|
||||
protected void addParameterDefintions(List<ParameterDefinition> paramList)
|
||||
{
|
||||
paramList.add(new ParameterDefinitionImpl(PARAM_PACKAGE_NAME, DataTypeDefinition.TEXT, true,
|
||||
getParamDisplayLabel(PARAM_PACKAGE_NAME)));
|
||||
paramList.add(new ParameterDefinitionImpl(PARAM_DESTINATION_FOLDER, DataTypeDefinition.NODE_REF, true,
|
||||
getParamDisplayLabel(PARAM_DESTINATION_FOLDER)));
|
||||
}
|
||||
|
||||
}
|
@@ -17,6 +17,7 @@
|
||||
package org.alfresco.repo.content;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -241,17 +242,28 @@ public class RoutingContentService implements ContentService
|
||||
{
|
||||
// get the property value
|
||||
ContentData contentData = null;
|
||||
|
||||
Serializable propValue = nodeService.getProperty(nodeRef, propertyQName);
|
||||
if (propValue instanceof Collection)
|
||||
{
|
||||
Collection colPropValue = (Collection)propValue;
|
||||
if (colPropValue.size() > 0)
|
||||
{
|
||||
propValue = (Serializable)colPropValue.iterator().next();
|
||||
}
|
||||
}
|
||||
if (propValue instanceof ContentData)
|
||||
{
|
||||
contentData = (ContentData)propValue;
|
||||
}
|
||||
|
||||
// ensure that the node property is of type content
|
||||
if (contentData == null)
|
||||
{
|
||||
// if no value or a value other content, and a property definition has been provided, ensure that it's CONTENT or ANY
|
||||
PropertyDefinition contentPropDef = dictionaryService.getProperty(propertyQName);
|
||||
if (contentPropDef == null || !(contentPropDef.getDataType().getName().equals(DataTypeDefinition.CONTENT)))
|
||||
if (contentPropDef != null &&
|
||||
(!(contentPropDef.getDataType().getName().equals(DataTypeDefinition.CONTENT) ||
|
||||
contentPropDef.getDataType().getName().equals(DataTypeDefinition.ANY))))
|
||||
{
|
||||
throw new InvalidTypeException("The node property must be of type content: \n" +
|
||||
" node: " + nodeRef + "\n" +
|
||||
|
@@ -258,22 +258,22 @@ import org.alfresco.service.namespace.QName;
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable)
|
||||
*/
|
||||
public void value(NodeRef nodeRef, QName property, Object value)
|
||||
public void value(NodeRef nodeRef, QName property, Object value, int index)
|
||||
{
|
||||
for (Exporter exporter : exporters)
|
||||
{
|
||||
exporter.value(nodeRef, property, value);
|
||||
exporter.value(nodeRef, property, value, index);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream)
|
||||
*/
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData)
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
|
||||
{
|
||||
for (Exporter exporter : exporters)
|
||||
{
|
||||
exporter.content(nodeRef, property, content, contentData);
|
||||
exporter.content(nodeRef, property, content, contentData, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -215,7 +215,7 @@ public class ExporterComponent
|
||||
try
|
||||
{
|
||||
XMLWriter writer = new XMLWriter(viewWriter, format);
|
||||
return new ViewXMLExporter(namespaceService, nodeService, dictionaryService, permissionService, writer);
|
||||
return new ViewXMLExporter(namespaceService, nodeService, searchService, dictionaryService, permissionService, writer);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
@@ -399,14 +399,18 @@ public class ExporterComponent
|
||||
|
||||
if (value instanceof Collection)
|
||||
{
|
||||
exporter.startValueCollection(nodeRef, property);
|
||||
int index = 0;
|
||||
for (Object valueInCollection : (Collection)value)
|
||||
{
|
||||
walkProperty(nodeRef, property, valueInCollection, parameters, exporter);
|
||||
walkProperty(nodeRef, property, valueInCollection, index, parameters, exporter);
|
||||
index++;
|
||||
}
|
||||
exporter.endValueCollection(nodeRef, property);
|
||||
}
|
||||
else
|
||||
{
|
||||
walkProperty(nodeRef, property, value, parameters, exporter);
|
||||
walkProperty(nodeRef, property, value, -1, parameters, exporter);
|
||||
}
|
||||
|
||||
// end export of property
|
||||
@@ -468,10 +472,11 @@ public class ExporterComponent
|
||||
* @param nodeRef
|
||||
* @param property
|
||||
* @param value
|
||||
* @param index
|
||||
* @param parameters
|
||||
* @param exporter
|
||||
*/
|
||||
private void walkProperty(NodeRef nodeRef, QName property, Object value, ExporterCrawlerParameters parameters, Exporter exporter)
|
||||
private void walkProperty(NodeRef nodeRef, QName property, Object value, int index, ExporterCrawlerParameters parameters, Exporter exporter)
|
||||
{
|
||||
// determine data type of value
|
||||
PropertyDefinition propDef = dictionaryService.getProperty(property);
|
||||
@@ -495,12 +500,12 @@ public class ExporterComponent
|
||||
// Export non content data types
|
||||
try
|
||||
{
|
||||
exporter.value(nodeRef, property, value);
|
||||
exporter.value(nodeRef, property, value, index);
|
||||
}
|
||||
catch(TypeConversionException e)
|
||||
{
|
||||
exporter.warning("Value of property " + property + " could not be converted to xml string");
|
||||
exporter.value(nodeRef, property, value.toString());
|
||||
exporter.value(nodeRef, property, value.toString(), index);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -512,7 +517,7 @@ public class ExporterComponent
|
||||
// export an empty url for the content
|
||||
ContentData contentData = (ContentData)value;
|
||||
ContentData noContentURL = new ContentData("", contentData.getMimetype(), contentData.getSize(), contentData.getEncoding());
|
||||
exporter.content(nodeRef, property, null, noContentURL);
|
||||
exporter.content(nodeRef, property, null, noContentURL, index);
|
||||
exporter.warning("Skipped content for property " + property + " on node " + nodeRef);
|
||||
}
|
||||
else
|
||||
@@ -520,7 +525,7 @@ public class ExporterComponent
|
||||
InputStream inputStream = reader.getContentInputStream();
|
||||
try
|
||||
{
|
||||
exporter.content(nodeRef, property, inputStream, reader.getContentData());
|
||||
exporter.content(nodeRef, property, inputStream, reader.getContentData(), index);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@@ -160,12 +160,12 @@ public class ExporterComponentTest extends BaseSpringTest
|
||||
// System.out.println("TestProgress: end value collection: node " + nodeRef + " , property " + property);
|
||||
}
|
||||
|
||||
public void value(NodeRef nodeRef, QName property, Object value)
|
||||
public void value(NodeRef nodeRef, QName property, Object value, int index)
|
||||
{
|
||||
// System.out.println("TestProgress: single value " + value);
|
||||
}
|
||||
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData)
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
|
||||
{
|
||||
// System.out.println("TestProgress: content stream ");
|
||||
}
|
||||
|
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* 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.repo.exporter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.service.cmr.model.FileExistsException;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
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.view.Exporter;
|
||||
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.RepositoryExporterService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
|
||||
|
||||
/**
|
||||
* Full Repository Export Service
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class RepositoryExporterComponent implements RepositoryExporterService
|
||||
{
|
||||
private static final String STOREREF_KEY = "storeRef";
|
||||
private static final String PACKAGENAME_KEY = "packageName";
|
||||
|
||||
// component dependencies
|
||||
private ExporterService exporterService;
|
||||
private MimetypeService mimetypeService;
|
||||
private FileFolderService fileFolderService;
|
||||
private NodeService nodeService;
|
||||
private List<Properties> exportStores;
|
||||
|
||||
|
||||
public void setExporterService(ExporterService exporterService)
|
||||
{
|
||||
this.exporterService = exporterService;
|
||||
}
|
||||
|
||||
public void setMimetypeService(MimetypeService mimetypeService)
|
||||
{
|
||||
this.mimetypeService = mimetypeService;
|
||||
}
|
||||
|
||||
public void setFileFolderService(FileFolderService fileFolderService)
|
||||
{
|
||||
this.fileFolderService = fileFolderService;
|
||||
}
|
||||
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setStores(List<Properties> exportStores)
|
||||
{
|
||||
this.exportStores = exportStores;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.RepositoryExporterService#export()
|
||||
*/
|
||||
public FileExportHandle[] export(String packageName)
|
||||
{
|
||||
List<FileExportHandle> exportHandles = exportStores(exportStores, packageName, new TempFileExporter());
|
||||
return exportHandles.toArray(new FileExportHandle[exportHandles.size()]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.RepositoryExporterService#export(java.io.File)
|
||||
*/
|
||||
public FileExportHandle[] export(File directoryDestination, String packageName)
|
||||
{
|
||||
ParameterCheck.mandatory("directoryDestination", directoryDestination);
|
||||
if (!directoryDestination.isDirectory())
|
||||
{
|
||||
throw new ExporterException("Export location " + directoryDestination.getAbsolutePath() + " is not a directory");
|
||||
}
|
||||
|
||||
List<FileExportHandle> exportHandles = exportStores(exportStores, packageName, new FileExporter(directoryDestination));
|
||||
return exportHandles.toArray(new FileExportHandle[exportHandles.size()]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.RepositoryExporterService#export(org.alfresco.service.cmr.repository.NodeRef)
|
||||
*/
|
||||
public RepositoryExportHandle[] export(NodeRef repositoryDestination, String packageName)
|
||||
{
|
||||
ParameterCheck.mandatory("repositoryDestination", repositoryDestination);
|
||||
FileInfo destInfo = fileFolderService.getFileInfo(repositoryDestination);
|
||||
if (destInfo == null || !destInfo.isFolder())
|
||||
{
|
||||
throw new ExporterException("Repository destination " + repositoryDestination + " is not a folder.");
|
||||
}
|
||||
|
||||
List<FileExportHandle> exportHandles = exportStores(exportStores, packageName, new TempFileExporter());
|
||||
List<RepositoryExportHandle> repoExportHandles = new ArrayList<RepositoryExportHandle>(exportHandles.size());
|
||||
for (FileExportHandle exportHandle : exportHandles)
|
||||
{
|
||||
String description = I18NUtil.getMessage("export.store.package.description", new Object[] { exportHandle.storeRef.getIdentifier() });
|
||||
NodeRef repoExportFile = addExportFile(repositoryDestination, exportHandle.packageName, description, exportHandle.exportFile);
|
||||
RepositoryExportHandle handle = new RepositoryExportHandle();
|
||||
handle.storeRef = exportHandle.storeRef;
|
||||
handle.packageName = exportHandle.packageName;
|
||||
handle.exportFile = repoExportFile;
|
||||
repoExportHandles.add(handle);
|
||||
}
|
||||
|
||||
return repoExportHandles.toArray(new RepositoryExportHandle[repoExportHandles.size()]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a file system based .acp file into the repository
|
||||
*
|
||||
* @param repoDestination location within repository to place .acp file
|
||||
* @param packageName acp package name
|
||||
* @param packageDescription acp package description
|
||||
* @param exportFile the .acp file
|
||||
* @return node reference to import .acp file
|
||||
*/
|
||||
private NodeRef addExportFile(NodeRef repoDestination, String packageName, String packageDescription, File exportFile)
|
||||
{
|
||||
//
|
||||
// import temp file into repository
|
||||
//
|
||||
|
||||
// determine if file already exists
|
||||
String fileName = packageName + "." + ACPExportPackageHandler.ACP_EXTENSION;
|
||||
List<String> paths = new ArrayList<String>();
|
||||
paths.add(fileName);
|
||||
try
|
||||
{
|
||||
FileInfo fileInfo = fileFolderService.resolveNamePath(repoDestination, paths);
|
||||
// Note: file already exists - delete
|
||||
fileFolderService.delete(fileInfo.getNodeRef());
|
||||
}
|
||||
catch (org.alfresco.service.cmr.model.FileNotFoundException e)
|
||||
{
|
||||
// Note: file does not exist - no need to delete
|
||||
}
|
||||
|
||||
// create acp file in repository
|
||||
NodeRef exportFileNodeRef = null;
|
||||
try
|
||||
{
|
||||
FileInfo fileInfo = fileFolderService.create(repoDestination, fileName, ContentModel.TYPE_CONTENT);
|
||||
ContentWriter writer = fileFolderService.getWriter(fileInfo.getNodeRef());
|
||||
writer.setMimetype(MimetypeMap.MIMETYPE_ACP);
|
||||
writer.putContent(exportFile);
|
||||
exportFileNodeRef = fileInfo.getNodeRef();
|
||||
|
||||
// add a title for Web Client viewing
|
||||
Map<QName, Serializable> titledProps = new HashMap<QName, Serializable>(3, 1.0f);
|
||||
titledProps.put(ContentModel.PROP_TITLE, packageName);
|
||||
titledProps.put(ContentModel.PROP_DESCRIPTION, packageDescription);
|
||||
nodeService.addAspect(exportFileNodeRef, ContentModel.ASPECT_TITLED, titledProps);
|
||||
|
||||
}
|
||||
catch (FileExistsException e)
|
||||
{
|
||||
// Note: shouldn't get here
|
||||
}
|
||||
|
||||
return exportFileNodeRef;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Contract for exporting a store
|
||||
*
|
||||
* @author davidc
|
||||
*
|
||||
* @param <ExportHandleType>
|
||||
*/
|
||||
private interface ExportStore<ExportHandleType extends ExportHandle>
|
||||
{
|
||||
public ExportHandleType exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enumerate list of pre-configured Stores and export one by one
|
||||
*
|
||||
* @param <ExportHandle> type of export file handle
|
||||
* @param stores the list of stores to export
|
||||
* @param exportStore the exporter call-back for handling the actual export
|
||||
* @return the list export file handles
|
||||
*/
|
||||
private <ExportHandleType extends ExportHandle> List<ExportHandleType> exportStores(List<Properties> stores, String packageName, ExportStore<ExportHandleType> exportStore)
|
||||
{
|
||||
List<ExportHandleType> exportHandles = new ArrayList<ExportHandleType>(stores.size());
|
||||
for (Properties store : stores)
|
||||
{
|
||||
// retrieve store reference to export
|
||||
String storeRefStr = (String)store.get(STOREREF_KEY);
|
||||
if (storeRefStr == null || storeRefStr.length() == 0)
|
||||
{
|
||||
throw new ExporterException("Store Reference has not been provided.");
|
||||
}
|
||||
StoreRef storeRef = new StoreRef(storeRefStr);
|
||||
|
||||
// retrieve package name to export into
|
||||
String storePackageName = (String)store.get(PACKAGENAME_KEY);
|
||||
if (storePackageName == null || storePackageName.length() == 0)
|
||||
{
|
||||
storePackageName = storeRef.getIdentifier();
|
||||
}
|
||||
String completePackageName = (packageName == null) ? storePackageName : packageName + "_" + storePackageName;
|
||||
|
||||
// now export
|
||||
// NOTE: For now, do not provide exporter progress
|
||||
ExporterCrawlerParameters exportParameters = getExportParameters(storeRef);
|
||||
ExportHandleType exportHandle = exportStore.exportStore(exportParameters, completePackageName, null);
|
||||
exportHandles.add(exportHandle);
|
||||
}
|
||||
|
||||
return exportHandles;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get export parameters for exporting a complete store
|
||||
*
|
||||
* @param storeRef store reference to export
|
||||
* @return the parameters for exporting the complete store
|
||||
*/
|
||||
private ExporterCrawlerParameters getExportParameters(StoreRef storeRef)
|
||||
{
|
||||
ExporterCrawlerParameters parameters = new ExporterCrawlerParameters();
|
||||
parameters.setExportFrom(new Location(storeRef));
|
||||
parameters.setCrawlSelf(true);
|
||||
parameters.setCrawlChildNodes(true);
|
||||
parameters.setCrawlContent(true);
|
||||
parameters.setCrawlAssociations(true);
|
||||
parameters.setCrawlNullProperties(true);
|
||||
parameters.setExcludeNamespaceURIs(new String[] {});
|
||||
return parameters;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Export a Store to a temporary file
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
private class TempFileExporter implements ExportStore<FileExportHandle>
|
||||
{
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.exporter.RepositoryExporterComponent.ExportStore#exportStore(org.alfresco.service.cmr.view.ExporterCrawlerParameters, java.lang.String, org.alfresco.service.cmr.view.Exporter)
|
||||
*/
|
||||
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);
|
||||
|
||||
// create acp export handler around the temp file
|
||||
File dataFile = new File(packageName);
|
||||
File contentDir = new File(packageName);
|
||||
try
|
||||
{
|
||||
OutputStream outputStream = new FileOutputStream(tempFile);
|
||||
ACPExportPackageHandler acpHandler = new ACPExportPackageHandler(outputStream, dataFile, contentDir, mimetypeService);
|
||||
|
||||
// export the store
|
||||
exporterService.exportView(acpHandler, exportParameters, progress);
|
||||
}
|
||||
catch(FileNotFoundException e)
|
||||
{
|
||||
tempFile.delete();
|
||||
throw new ExporterException("Failed to create temporary file for holding export of store " + exportParameters.getExportFrom().getStoreRef());
|
||||
}
|
||||
|
||||
// return handle onto temp file
|
||||
FileExportHandle handle = new FileExportHandle();
|
||||
handle.storeRef = exportParameters.getExportFrom().getStoreRef();
|
||||
handle.packageName = packageName;
|
||||
handle.exportFile = tempFile;
|
||||
return handle;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Export a Store to a file in a specified folder
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
private class FileExporter implements ExportStore<FileExportHandle>
|
||||
{
|
||||
private File directoryDestination;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param directoryDestination destination file system folder to create export file
|
||||
*/
|
||||
public FileExporter(File directoryDestination)
|
||||
{
|
||||
this.directoryDestination = directoryDestination;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.exporter.RepositoryExporterComponent.ExportStore#exportStore(org.alfresco.service.cmr.view.ExporterCrawlerParameters, java.lang.String, org.alfresco.service.cmr.view.Exporter)
|
||||
*/
|
||||
public FileExportHandle exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress)
|
||||
{
|
||||
// create a file to hold the acp export
|
||||
File file = new File(directoryDestination, packageName + "." + ACPExportPackageHandler.ACP_EXTENSION);
|
||||
|
||||
// create acp export handler around the temp file
|
||||
File dataFile = new File(packageName);
|
||||
File contentDir = new File(packageName);
|
||||
try
|
||||
{
|
||||
OutputStream outputStream = new FileOutputStream(file);
|
||||
ACPExportPackageHandler acpHandler = new ACPExportPackageHandler(outputStream, dataFile, contentDir, mimetypeService);
|
||||
|
||||
// export the store
|
||||
exporterService.exportView(acpHandler, exportParameters, progress);
|
||||
}
|
||||
catch(FileNotFoundException e)
|
||||
{
|
||||
file.delete();
|
||||
throw new ExporterException("Failed to create file " + file.getAbsolutePath() + " for holding the export of store " + exportParameters.getExportFrom().getStoreRef());
|
||||
}
|
||||
|
||||
// return handle onto temp file
|
||||
FileExportHandle handle = new FileExportHandle();
|
||||
handle.storeRef = exportParameters.getExportFrom().getStoreRef();
|
||||
handle.packageName = packageName;
|
||||
handle.exportFile = file;
|
||||
return handle;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Export a store to Repository File
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
private class RepositoryFileExporter implements ExportStore<RepositoryExportHandle>
|
||||
{
|
||||
private TempFileExporter tempFileExporter = new TempFileExporter();
|
||||
private NodeRef repoDestination;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param repoDestination destination within repository to create export file
|
||||
*/
|
||||
public RepositoryFileExporter(NodeRef repoDestination)
|
||||
{
|
||||
this.repoDestination = repoDestination;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.exporter.RepositoryExporterComponent.ExportStore#exportStore(org.alfresco.service.cmr.view.ExporterCrawlerParameters, java.lang.String, org.alfresco.service.cmr.view.Exporter)
|
||||
*/
|
||||
public RepositoryExportHandle exportStore(ExporterCrawlerParameters exportParameters, String packageName, Exporter progress)
|
||||
{
|
||||
// export acp to temporary file
|
||||
FileExportHandle tempFile = tempFileExporter.exportStore(exportParameters, packageName, progress);
|
||||
|
||||
String description = I18NUtil.getMessage("export.store.package.description", new Object[] { tempFile.storeRef.getIdentifier() });
|
||||
NodeRef repoExportFile = addExportFile(repoDestination, packageName, description, tempFile.exportFile);
|
||||
RepositoryExportHandle handle = new RepositoryExportHandle();
|
||||
handle.storeRef = exportParameters.getExportFrom().getStoreRef();
|
||||
handle.packageName = packageName;
|
||||
handle.exportFile = repoExportFile;
|
||||
return handle;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.repo.exporter;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.model.FileFolderService;
|
||||
import org.alfresco.service.cmr.model.FileInfo;
|
||||
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.view.RepositoryExporterService;
|
||||
import org.alfresco.service.cmr.view.RepositoryExporterService.FileExportHandle;
|
||||
import org.alfresco.service.cmr.view.RepositoryExporterService.RepositoryExportHandle;
|
||||
import org.alfresco.util.BaseSpringTest;
|
||||
|
||||
|
||||
public class RepositoryExporterComponentTest extends BaseSpringTest
|
||||
{
|
||||
private RepositoryExporterService repositoryService;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private NodeService nodeService;
|
||||
private FileFolderService fileFolderService;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onSetUpInTransaction() throws Exception
|
||||
{
|
||||
this.nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName());
|
||||
this.fileFolderService = (FileFolderService)applicationContext.getBean(ServiceRegistry.FILE_FOLDER_SERVICE.getLocalName());
|
||||
this.repositoryService = (RepositoryExporterService)applicationContext.getBean("repositoryExporterComponent");
|
||||
this.authenticationComponent = (AuthenticationComponent)this.applicationContext.getBean("authenticationComponent");
|
||||
this.authenticationComponent.setSystemUserAsCurrentUser();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTearDownInTransaction() throws Exception
|
||||
{
|
||||
authenticationComponent.clearCurrentSecurityContext();
|
||||
super.onTearDownInTransaction();
|
||||
}
|
||||
|
||||
|
||||
public void testDummy()
|
||||
{
|
||||
}
|
||||
|
||||
public void xtestTempFileExport()
|
||||
throws Exception
|
||||
{
|
||||
FileExportHandle[] handles = repositoryService.export("test");
|
||||
assertNotNull(handles);
|
||||
assertEquals(4, handles.length);
|
||||
for (FileExportHandle tempFile : handles)
|
||||
{
|
||||
assertTrue(tempFile.exportFile.exists());
|
||||
}
|
||||
}
|
||||
|
||||
public void xtestRepositoryExport()
|
||||
throws Exception
|
||||
{
|
||||
// Create a temp store to hold exports
|
||||
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
|
||||
NodeRef rootNode = nodeService.getRootNode(storeRef);
|
||||
FileInfo container = fileFolderService.create(rootNode, "export", ContentModel.TYPE_FOLDER);
|
||||
|
||||
// Export stores
|
||||
RepositoryExportHandle[] handles = repositoryService.export(container.getNodeRef(), "test");
|
||||
assertNotNull(handles);
|
||||
assertEquals(4, handles.length);
|
||||
for (RepositoryExportHandle handle : handles)
|
||||
{
|
||||
assertTrue(nodeService.exists(handle.exportFile));
|
||||
}
|
||||
|
||||
setComplete();
|
||||
}
|
||||
|
||||
}
|
@@ -204,19 +204,19 @@ import org.alfresco.util.ParameterCheck;
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable)
|
||||
*/
|
||||
public void value(NodeRef nodeRef, QName property, Object value)
|
||||
public void value(NodeRef nodeRef, QName property, Object value, int index)
|
||||
{
|
||||
exporter.value(nodeRef, property, value);
|
||||
exporter.value(nodeRef, property, value, index);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream)
|
||||
*/
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData)
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
|
||||
{
|
||||
// Handle the stream by converting it to a URL and export the URL
|
||||
ContentData exportedContentData = streamHandler.exportContent(content, contentData);
|
||||
value(nodeRef, property, exportedContentData);
|
||||
value(nodeRef, property, exportedContentData, index);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@@ -17,7 +17,7 @@
|
||||
package org.alfresco.repo.exporter;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
@@ -28,6 +28,7 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.Path;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.cmr.security.AccessPermission;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.cmr.view.Exporter;
|
||||
@@ -98,6 +99,7 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
// Service dependencies
|
||||
private NamespaceService namespaceService;
|
||||
private NodeService nodeService;
|
||||
private SearchService searchService;
|
||||
private DictionaryService dictionaryService;
|
||||
private PermissionService permissionService;
|
||||
|
||||
@@ -113,11 +115,12 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
* @param nodeService node service
|
||||
* @param contentHandler content handler
|
||||
*/
|
||||
ViewXMLExporter(NamespaceService namespaceService, NodeService nodeService,
|
||||
ViewXMLExporter(NamespaceService namespaceService, NodeService nodeService, SearchService searchService,
|
||||
DictionaryService dictionaryService, PermissionService permissionService, ContentHandler contentHandler)
|
||||
{
|
||||
this.namespaceService = namespaceService;
|
||||
this.nodeService = nodeService;
|
||||
this.searchService = searchService;
|
||||
this.dictionaryService = dictionaryService;
|
||||
this.permissionService = permissionService;
|
||||
this.contentHandler = contentHandler;
|
||||
@@ -492,7 +495,7 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable)
|
||||
*/
|
||||
public void value(NodeRef nodeRef, QName property, Object value)
|
||||
public void value(NodeRef nodeRef, QName property, Object value, int index)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -512,12 +515,16 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
// convert node references to paths
|
||||
if (value instanceof NodeRef)
|
||||
{
|
||||
Path nodeRefPath = createRelativePath(context.getExportOf(), nodeRef, (NodeRef)value);
|
||||
value = (nodeRefPath == null) ? null : nodeRefPath.toPrefixString(namespaceService);
|
||||
NodeRef valueNodeRef = (NodeRef)value;
|
||||
if (nodeRef.getStoreRef().equals(valueNodeRef.getStoreRef()))
|
||||
{
|
||||
Path nodeRefPath = createRelativePath(context.getExportOf(), nodeRef, valueNodeRef);
|
||||
value = (nodeRefPath == null) ? null : nodeRefPath.toPrefixString(namespaceService);
|
||||
}
|
||||
}
|
||||
|
||||
// output value wrapper if value is null or property data type is ANY
|
||||
if (value == null || valueDataType != null)
|
||||
// output value wrapper if value is null or property data type is ANY or value is part of collection
|
||||
if (value == null || valueDataType != null || index != -1)
|
||||
{
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
if (value == null)
|
||||
@@ -539,7 +546,7 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
}
|
||||
|
||||
// output value wrapper if property data type is any
|
||||
if (value == null || valueDataType != null)
|
||||
if (value == null || valueDataType != null || index != -1)
|
||||
{
|
||||
contentHandler.endElement(NamespaceService.REPOSITORY_VIEW_PREFIX, VALUE_LOCALNAME, toPrefixString(VALUE_QNAME));
|
||||
}
|
||||
@@ -550,74 +557,10 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.util.Collection)
|
||||
*/
|
||||
public void value(NodeRef nodeRef, QName property, Collection values)
|
||||
{
|
||||
try
|
||||
{
|
||||
PropertyDefinition propDef = dictionaryService.getProperty(property);
|
||||
DataTypeDefinition dataTypeDef = (propDef == null) ? null : propDef.getDataType();
|
||||
|
||||
// start collection
|
||||
contentHandler.startElement(NamespaceService.REPOSITORY_VIEW_PREFIX, VALUES_LOCALNAME, toPrefixString(VALUES_QNAME), EMPTY_ATTRIBUTES);
|
||||
|
||||
for (Object value : values)
|
||||
{
|
||||
// determine data type of value
|
||||
QName valueDataType = null;
|
||||
if (dataTypeDef == null || dataTypeDef.getName().equals(DataTypeDefinition.ANY))
|
||||
{
|
||||
dataTypeDef = (value == null) ? null : dictionaryService.getDataType(value.getClass());
|
||||
if (dataTypeDef != null)
|
||||
{
|
||||
valueDataType = dataTypeDef.getName();
|
||||
}
|
||||
}
|
||||
|
||||
// output value wrapper with datatype
|
||||
AttributesImpl attrs = new AttributesImpl();
|
||||
if (value == null)
|
||||
{
|
||||
attrs.addAttribute(NamespaceService.REPOSITORY_VIEW_PREFIX, ISNULL_LOCALNAME, ISNULL_QNAME.toPrefixString(), null, "true");
|
||||
}
|
||||
if (valueDataType != null)
|
||||
{
|
||||
attrs.addAttribute(NamespaceService.REPOSITORY_VIEW_PREFIX, DATATYPE_LOCALNAME, DATATYPE_QNAME.toPrefixString(), null, toPrefixString(valueDataType));
|
||||
}
|
||||
contentHandler.startElement(NamespaceService.REPOSITORY_VIEW_PREFIX, VALUE_LOCALNAME, toPrefixString(VALUE_QNAME), attrs);
|
||||
|
||||
// convert node references to paths
|
||||
if (value instanceof NodeRef)
|
||||
{
|
||||
value = createRelativePath(context.getExportOf(), nodeRef, (NodeRef)value).toPrefixString(namespaceService);
|
||||
}
|
||||
|
||||
// output value
|
||||
String strValue = (String)DefaultTypeConverter.INSTANCE.convert(String.class, value);
|
||||
if (strValue != null)
|
||||
{
|
||||
contentHandler.characters(strValue.toCharArray(), 0, strValue.length());
|
||||
}
|
||||
|
||||
// output value wrapper if property data type is any
|
||||
contentHandler.endElement(NamespaceService.REPOSITORY_VIEW_PREFIX, VALUE_LOCALNAME, toPrefixString(VALUE_QNAME));
|
||||
}
|
||||
|
||||
// end collection
|
||||
contentHandler.endElement(NamespaceService.REPOSITORY_VIEW_PREFIX, VALUES_LOCALNAME, toPrefixString(VALUES_QNAME));
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
throw new ExporterException("Failed to process multi-value event - nodeRef " + nodeRef + "; property " + toPrefixString(property), e);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream)
|
||||
*/
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData)
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
|
||||
{
|
||||
// TODO: Base64 encode content and send out via Content Handler
|
||||
}
|
||||
@@ -770,9 +713,9 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
return null;
|
||||
}
|
||||
|
||||
Path rootPath = nodeService.getPath(rootRef);
|
||||
Path fromPath = nodeService.getPath(fromRef);
|
||||
Path toPath = nodeService.getPath(toRef);
|
||||
Path rootPath = createIndexedPath(rootRef, nodeService.getPath(rootRef));
|
||||
Path fromPath = createIndexedPath(fromRef, nodeService.getPath(fromRef));
|
||||
Path toPath = createIndexedPath(toRef, nodeService.getPath(toRef));
|
||||
Path relativePath = null;
|
||||
|
||||
try
|
||||
@@ -840,4 +783,43 @@ import org.xml.sax.helpers.AttributesImpl;
|
||||
return relativePath;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to convert a path into an indexed path which uniquely identifies a node
|
||||
*
|
||||
* @param nodeRef
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private Path createIndexedPath(NodeRef nodeRef, Path path)
|
||||
{
|
||||
// Add indexes for same name siblings
|
||||
// TODO: Look at more efficient approach
|
||||
for (int i = path.size() - 1; i >= 0; i--)
|
||||
{
|
||||
Path.Element pathElement = path.get(i);
|
||||
if (i > 0 && pathElement instanceof Path.ChildAssocElement)
|
||||
{
|
||||
int index = 1; // for xpath index compatibility
|
||||
String searchPath = path.subPath(i).toPrefixString(namespaceService);
|
||||
List<NodeRef> siblings = searchService.selectNodes(nodeRef, searchPath, null, namespaceService, false);
|
||||
if (siblings.size() > 1)
|
||||
{
|
||||
ChildAssociationRef childAssoc = ((Path.ChildAssocElement)pathElement).getRef();
|
||||
NodeRef childRef = childAssoc.getChildRef();
|
||||
for (NodeRef sibling : siblings)
|
||||
{
|
||||
if (sibling.equals(childRef))
|
||||
{
|
||||
childAssoc.setNthSibling(index);
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
@@ -39,6 +39,7 @@ import org.alfresco.service.cmr.view.ImporterBinding;
|
||||
import org.alfresco.service.cmr.view.ImporterService;
|
||||
import org.alfresco.service.cmr.view.Location;
|
||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.TempFileProvider;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
@@ -202,6 +203,11 @@ public class ExportSourceImporter implements ImporterJobSPI
|
||||
return false;
|
||||
}
|
||||
|
||||
public QName[] getExcludedClasses()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -75,6 +75,14 @@ public interface Importer
|
||||
*/
|
||||
public NodeRef resolvePath(String path);
|
||||
|
||||
/**
|
||||
* Is excluded Content Model Class?
|
||||
*
|
||||
* @param QName the class name to test
|
||||
* @return true => the provided class is excluded from import
|
||||
*/
|
||||
public boolean isExcludedClass(QName className);
|
||||
|
||||
/**
|
||||
* Signal completion of node import
|
||||
*
|
||||
|
@@ -313,7 +313,7 @@ public class ImporterBootstrap implements ApplicationListener
|
||||
}
|
||||
|
||||
UserTransaction userTransaction = transactionService.getUserTransaction();
|
||||
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||
authenticationComponent.setSystemUserAsCurrentUser();
|
||||
|
||||
try
|
||||
{
|
||||
@@ -550,7 +550,7 @@ public class ImporterBootstrap implements ApplicationListener
|
||||
public UUID_BINDING getUUIDBinding()
|
||||
{
|
||||
// always use create new strategy for bootstrap import
|
||||
return UUID_BINDING.CREATE_NEW;
|
||||
return UUID_BINDING.CREATE_NEW_WITH_UUID;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -561,6 +561,16 @@ public class ImporterBootstrap implements ApplicationListener
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.ImporterBinding#getExcludedClasses()
|
||||
*/
|
||||
public QName[] getExcludedClasses()
|
||||
{
|
||||
// Note: Do not exclude any classes, we want to import all
|
||||
return new QName[] {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -401,6 +401,7 @@ public class ImporterComponent
|
||||
private ImportPackageHandler streamHandler;
|
||||
private NodeImporterStrategy importStrategy;
|
||||
private UpdateExistingNodeImporterStrategy updateStrategy;
|
||||
private QName[] excludedClasses;
|
||||
|
||||
// Import tracking
|
||||
private List<ImportedNodeRef> nodeRefs = new ArrayList<ImportedNodeRef>();
|
||||
@@ -422,6 +423,16 @@ public class ImporterComponent
|
||||
this.streamHandler = streamHandler;
|
||||
this.importStrategy = createNodeImporterStrategy(binding == null ? null : binding.getUUIDBinding());
|
||||
this.updateStrategy = new UpdateExistingNodeImporterStrategy();
|
||||
|
||||
// initialise list of content models to exclude from import
|
||||
if (binding == null || binding.getExcludedClasses() == null)
|
||||
{
|
||||
this.excludedClasses = new QName[] { ContentModel.ASPECT_REFERENCEABLE, ContentModel.ASPECT_VERSIONABLE };
|
||||
}
|
||||
else
|
||||
{
|
||||
this.excludedClasses = binding.getExcludedClasses();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -440,6 +451,10 @@ public class ImporterComponent
|
||||
{
|
||||
return new CreateNewNodeImporterStrategy(true);
|
||||
}
|
||||
else if (uuidBinding.equals(UUID_BINDING.CREATE_NEW_WITH_UUID))
|
||||
{
|
||||
return new CreateNewNodeImporterStrategy(false);
|
||||
}
|
||||
else if (uuidBinding.equals(UUID_BINDING.REMOVE_EXISTING))
|
||||
{
|
||||
return new RemoveExistingNodeImporterStrategy();
|
||||
@@ -652,6 +667,22 @@ public class ImporterComponent
|
||||
}
|
||||
return referencedRef;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.importer.Importer#isExcludedClass(org.alfresco.service.namespace.QName)
|
||||
*/
|
||||
public boolean isExcludedClass(QName className)
|
||||
{
|
||||
for (QName excludedClass : excludedClasses)
|
||||
{
|
||||
if (excludedClass.equals(className))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.importer.Importer#end()
|
||||
@@ -670,13 +701,16 @@ public class ImporterComponent
|
||||
List<NodeRef> resolvedRefs = new ArrayList<NodeRef>(unresolvedRefs.size());
|
||||
for (String unresolvedRef : unresolvedRefs)
|
||||
{
|
||||
NodeRef nodeRef = resolveImportedNodeRef(importedRef.context.getNodeRef(), unresolvedRef);
|
||||
if (nodeRef == null)
|
||||
if (unresolvedRef != null)
|
||||
{
|
||||
// TODO: Probably need an alternative mechanism here e.g. report warning
|
||||
throw new ImporterException("Failed to find item referenced (in property " + importedRef.property + ") as " + importedRef.value);
|
||||
NodeRef nodeRef = resolveImportedNodeRef(importedRef.context.getNodeRef(), unresolvedRef);
|
||||
if (nodeRef == null)
|
||||
{
|
||||
// TODO: Probably need an alternative mechanism here e.g. report warning
|
||||
throw new ImporterException("Failed to find item referenced (in property " + importedRef.property + ") as " + importedRef.value);
|
||||
}
|
||||
resolvedRefs.add(nodeRef);
|
||||
}
|
||||
resolvedRefs.add(nodeRef);
|
||||
}
|
||||
refProperty = (Serializable)resolvedRefs;
|
||||
}
|
||||
@@ -998,19 +1032,11 @@ public class ImporterComponent
|
||||
}
|
||||
catch(XPathException e)
|
||||
{
|
||||
// attempt to resolve as a node reference
|
||||
try
|
||||
{
|
||||
NodeRef directRef = new NodeRef(importedRef);
|
||||
if (nodeService.exists(directRef))
|
||||
{
|
||||
nodeRef = directRef;
|
||||
}
|
||||
}
|
||||
catch(AlfrescoRuntimeException e1)
|
||||
{
|
||||
// Note: Invalid reference format
|
||||
}
|
||||
nodeRef = new NodeRef(importedRef);
|
||||
}
|
||||
catch(AlfrescoRuntimeException e1)
|
||||
{
|
||||
// Note: Invalid reference format - try path search instead
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -459,8 +459,7 @@ public class NodeContext extends ElementContext
|
||||
*/
|
||||
private boolean isImportableClass(QName className)
|
||||
{
|
||||
return !(className.equals(ContentModel.ASPECT_REFERENCEABLE) ||
|
||||
className.equals(ContentModel.ASPECT_VERSIONABLE));
|
||||
return !getImporter().isExcludedClass(className);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@@ -178,7 +178,7 @@ public class StoreRedirectorProxyFactory<I> implements FactoryBean, Initializing
|
||||
// Otherwise, determine the apropriate implementation to invoke for
|
||||
// the service interface method
|
||||
Object binding = null;
|
||||
StoreRef storeRef = getStoreRef(args);
|
||||
StoreRef storeRef = getStoreRef(method.getParameterTypes(), args);
|
||||
if (storeRef == null)
|
||||
{
|
||||
binding = StoreRedirectorProxyFactory.this.defaultBinding;
|
||||
@@ -224,7 +224,7 @@ public class StoreRedirectorProxyFactory<I> implements FactoryBean, Initializing
|
||||
* @param args the method arguments
|
||||
* @return the store type (or null, if one is not specified)
|
||||
*/
|
||||
private StoreRef getStoreRef(Object[] args)
|
||||
private StoreRef getStoreRef(Class[] argTypes, Object[] args)
|
||||
{
|
||||
StoreRef storeRef = null;
|
||||
|
||||
@@ -233,17 +233,17 @@ public class StoreRedirectorProxyFactory<I> implements FactoryBean, Initializing
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Object arg : args)
|
||||
for (int i = 0; i < argTypes.length; i++)
|
||||
{
|
||||
// Extract store type from argument, if store type provided
|
||||
StoreRef argStoreRef = null;
|
||||
if (arg instanceof NodeRef)
|
||||
if (argTypes[i].equals(NodeRef.class))
|
||||
{
|
||||
argStoreRef = ((NodeRef) arg).getStoreRef();
|
||||
argStoreRef = ((NodeRef) args[i]).getStoreRef();
|
||||
}
|
||||
else if (arg instanceof StoreRef)
|
||||
else if (argTypes[i].equals(StoreRef.class))
|
||||
{
|
||||
argStoreRef = ((StoreRef) arg);
|
||||
argStoreRef = ((StoreRef) args[i]);
|
||||
}
|
||||
|
||||
// Only allow one store type
|
||||
|
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* 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.repo.version;
|
||||
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
|
||||
/**
|
||||
* Bootstrap Version Store
|
||||
*
|
||||
* @author David Caruana
|
||||
*/
|
||||
public class VersionBootstrap
|
||||
{
|
||||
private TransactionService transactionService;
|
||||
private NodeService nodeService;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private PermissionService permissionService;
|
||||
|
||||
|
||||
/**
|
||||
* Sets the Transaction Service
|
||||
*
|
||||
* @param userTransaction the user transaction
|
||||
*/
|
||||
public void setTransactionService(TransactionService transactionService)
|
||||
{
|
||||
this.transactionService = transactionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Node Service
|
||||
*
|
||||
* @param nodeService the node service
|
||||
*/
|
||||
public void setNodeService(NodeService nodeService)
|
||||
{
|
||||
this.nodeService = nodeService;
|
||||
}
|
||||
|
||||
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
|
||||
{
|
||||
this.authenticationComponent = authenticationComponent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setPermissionService(PermissionService permissionService)
|
||||
{
|
||||
this.permissionService = permissionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap the Version Store
|
||||
*/
|
||||
public void bootstrap()
|
||||
{
|
||||
UserTransaction userTransaction = transactionService.getUserTransaction();
|
||||
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||
|
||||
try
|
||||
{
|
||||
userTransaction.begin();
|
||||
|
||||
// Ensure that the version store has been created
|
||||
if (this.nodeService.exists(new StoreRef(StoreRef.PROTOCOL_WORKSPACE, VersionModel.STORE_ID)) == true)
|
||||
{
|
||||
userTransaction.rollback();
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreRef vStore = this.nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, VersionModel.STORE_ID);
|
||||
// TODO: For now there are no permissions on version access
|
||||
permissionService.setPermission(nodeService.getRootNode(vStore), permissionService.getAllAuthorities(), permissionService.getAllPermission(), true);
|
||||
userTransaction.commit();
|
||||
}
|
||||
}
|
||||
catch(Throwable e)
|
||||
{
|
||||
// rollback the transaction
|
||||
try { if (userTransaction != null) {userTransaction.rollback();} } catch (Exception ex) {}
|
||||
try {authenticationComponent.clearCurrentSecurityContext(); } catch (Exception ex) {}
|
||||
throw new AlfrescoRuntimeException("Bootstrap failed", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
authenticationComponent.clearCurrentSecurityContext();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -171,14 +171,26 @@ public interface Exporter
|
||||
public void startValueCollection(NodeRef nodeRef, QName property);
|
||||
|
||||
/**
|
||||
* Export single valued property
|
||||
* Export property value
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @param property the property name
|
||||
* @param value the value
|
||||
* @param index value index (or -1, if not part of multi-valued collection)
|
||||
*/
|
||||
public void value(NodeRef nodeRef, QName property, Object value);
|
||||
public void value(NodeRef nodeRef, QName property, Object value, int index);
|
||||
|
||||
/**
|
||||
* Export content stream property value
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @param property the property name
|
||||
* @param content the content stream
|
||||
* @param contentData content descriptor
|
||||
* @param index value index (or -1, if not part of multi-valued collection)
|
||||
*/
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index);
|
||||
|
||||
/**
|
||||
* Export end of value collection
|
||||
*
|
||||
@@ -187,16 +199,6 @@ public interface Exporter
|
||||
*/
|
||||
public void endValueCollection(NodeRef nodeRef, QName property);
|
||||
|
||||
/**
|
||||
* Export content stream property
|
||||
*
|
||||
* @param nodeRef the node reference
|
||||
* @param property the property name
|
||||
* @param content the content stream
|
||||
* @param contentData content descriptor
|
||||
*/
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData);
|
||||
|
||||
/**
|
||||
* Start export of associations
|
||||
*
|
||||
|
@@ -16,6 +16,8 @@
|
||||
*/
|
||||
package org.alfresco.service.cmr.view;
|
||||
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
|
||||
/**
|
||||
* Encapsulation of Import binding parameters
|
||||
@@ -30,7 +32,7 @@ public interface ImporterBinding
|
||||
*/
|
||||
public enum UUID_BINDING
|
||||
{
|
||||
CREATE_NEW, REMOVE_EXISTING, REPLACE_EXISTING, UPDATE_EXISTING, THROW_ON_COLLISION
|
||||
CREATE_NEW, CREATE_NEW_WITH_UUID, REMOVE_EXISTING, REPLACE_EXISTING, UPDATE_EXISTING, THROW_ON_COLLISION
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,4 +58,11 @@ public interface ImporterBinding
|
||||
*/
|
||||
public String getValue(String key);
|
||||
|
||||
/**
|
||||
* Gets the list of content model classes to exclude from import
|
||||
*
|
||||
* @return list of model class qnames to exclude (return null to indicate use of default list)
|
||||
*/
|
||||
public QName[] getExcludedClasses();
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
|
||||
|
||||
/**
|
||||
* Repository Export Service
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface RepositoryExporterService
|
||||
{
|
||||
|
||||
/**
|
||||
* Export complete Repository.
|
||||
*
|
||||
* Each store is exported to its own temporary .acp file
|
||||
*
|
||||
* @param packageName package name prefix for export .acp files
|
||||
* @return list of temporary export files
|
||||
*/
|
||||
public FileExportHandle[] export(String packageName);
|
||||
|
||||
/**
|
||||
* Export complete Repository.
|
||||
*
|
||||
* Each store is exported to a file held in the Repository.
|
||||
*
|
||||
* @param repositoryDestination location within Repository to hold .acp files
|
||||
* @param packageName package name prefix for export .acp files
|
||||
* @return list of repository held export files
|
||||
*/
|
||||
public RepositoryExportHandle[] export(NodeRef repositoryDestination, String packageName);
|
||||
|
||||
/**
|
||||
* Export complete Repository.
|
||||
*
|
||||
* @param directoryDestination location within File System to hold .acp files
|
||||
* @param packageName package name prefix for export .acp files
|
||||
* @return list of export files
|
||||
*/
|
||||
public FileExportHandle[] export(File directoryDestination, String packageName);
|
||||
|
||||
|
||||
/**
|
||||
* General Export Handle
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class ExportHandle
|
||||
{
|
||||
public StoreRef storeRef;
|
||||
public String packageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Exort Handle
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class FileExportHandle extends ExportHandle
|
||||
{
|
||||
public File exportFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repository File Export Handle
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class RepositoryExportHandle extends ExportHandle
|
||||
{
|
||||
public NodeRef exportFile;
|
||||
}
|
||||
|
||||
}
|
@@ -568,14 +568,14 @@ public final class Export extends Tool
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable)
|
||||
*/
|
||||
public void value(NodeRef nodeRef, QName property, Object value)
|
||||
public void value(NodeRef nodeRef, QName property, Object value, int index)
|
||||
{
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream)
|
||||
*/
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData)
|
||||
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
|
||||
{
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user