diff --git a/config/alfresco/avm-context.xml b/config/alfresco/avm-context.xml new file mode 100644 index 0000000000..0286419653 --- /dev/null +++ b/config/alfresco/avm-context.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/config/alfresco/bootstrap/Alfresco-Tutorial.pdf b/config/alfresco/bootstrap/Alfresco-Tutorial.pdf index 395b9c3ff6..65c4586319 100644 Binary files a/config/alfresco/bootstrap/Alfresco-Tutorial.pdf and b/config/alfresco/bootstrap/Alfresco-Tutorial.pdf differ diff --git a/config/alfresco/extension/custom-db-connection.properties.sample b/config/alfresco/extension/custom-db-connection.properties.sample index 44d5da9cf3..d09219b796 100644 --- a/config/alfresco/extension/custom-db-connection.properties.sample +++ b/config/alfresco/extension/custom-db-connection.properties.sample @@ -29,4 +29,12 @@ # SQLServer connection (requires jdts-1.2.jar or equivalent - http://jtds.sourceforge.net/) # #db.driver=net.sourceforge.jtds.jdbc.Driver -#db.url=jdbc:jtds:sqlserver://your-server-name/alfresco \ No newline at end of file +#db.url=jdbc:jtds:sqlserver://localhost/alfresco + +# +# SQLServer connection using Microsoft JDDB driver +# +#db.username=sa +#db.password=sa +#db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver +#db.url=jdbc:sqlserver://localhost;DatabaseName=alfresco diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties index ff250ed65c..736fe5d4ee 100644 --- a/config/alfresco/repository.properties +++ b/config/alfresco/repository.properties @@ -69,7 +69,7 @@ mail.port=25 mail.username=anonymous mail.password= # Set this value to UTF-8 or similar for encoding of email messages as required -mail.encoding= +mail.encoding=UTF-8 # System Configuration diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index 83d88a8a59..4dd47fc44c 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -5,7 +5,7 @@ # Version label version.major=1 -version.minor=3 +version.minor=4 version.revision=0 version.label=RC2 (dev) diff --git a/source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java b/source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java index cfcd5522b0..84e0d080db 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/CifsHelper.java @@ -276,8 +276,8 @@ public class CifsHelper // Read/write access - boolean hasPermission = permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED; - if (isReadOnly || !hasPermission) + boolean deniedPermission = permissionService.hasPermission(nodeRef, PermissionService.WRITE) == AccessStatus.DENIED; + if (isReadOnly || deniedPermission) { int attr = fileInfo.getFileAttributes(); if (( attr & FileAttribute.ReadOnly) == 0) diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java b/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java index f9d87c1849..954b82d55a 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java @@ -331,7 +331,7 @@ public class ContentDiskDriver implements DiskInterface, IOCtlInterface { logger.warn("Failed to rollback transaction", ex); } - } + } } // Check if the client side drag and drop appliction has been enabled diff --git a/source/java/org/alfresco/repo/action/executer/ExporterActionExecuter.java b/source/java/org/alfresco/repo/action/executer/ExporterActionExecuter.java index 1dd2c196dd..a6bbf1583e 100644 --- a/source/java/org/alfresco/repo/action/executer/ExporterActionExecuter.java +++ b/source/java/org/alfresco/repo/action/executer/ExporterActionExecuter.java @@ -218,9 +218,9 @@ public class ExporterActionExecuter extends ActionExecuterAbstractBase String packageName = (String)ruleAction.getParameterValue(PARAM_PACKAGE_NAME); // add the default Alfresco content package extension if an extension hasn't been given - if (packageName.indexOf(".") == -1) + if (!packageName.endsWith("." + ACPExportPackageHandler.ACP_EXTENSION)) { - packageName = packageName + "." + ACPExportPackageHandler.ACP_EXTENSION; + packageName += (packageName.charAt(packageName.length() -1) == '.') ? ACPExportPackageHandler.ACP_EXTENSION : "." + ACPExportPackageHandler.ACP_EXTENSION; } // set the name for the new node diff --git a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml index c969c6fe31..51e8fb8fc6 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml +++ b/source/java/org/alfresco/repo/domain/hibernate/Node.hbm.xml @@ -156,7 +156,6 @@ unique="false" not-null="false" /> - @@ -297,7 +296,19 @@ where status.key.protocol = :storeProtocol and status.key.identifier = :storeIdentifier and - status.deleted = :deleted and + status.node.id is not null and + status.changeTxnId = :changeTxnId + + + + select + status + from + org.alfresco.repo.domain.hibernate.NodeStatusImpl as status + where + status.key.protocol = :storeProtocol and + status.key.identifier = :storeIdentifier and + status.node.id is null and status.changeTxnId = :changeTxnId diff --git a/source/java/org/alfresco/repo/domain/hibernate/NodeStatusImpl.java b/source/java/org/alfresco/repo/domain/hibernate/NodeStatusImpl.java index 9b52b249af..77ea062ebb 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/NodeStatusImpl.java +++ b/source/java/org/alfresco/repo/domain/hibernate/NodeStatusImpl.java @@ -99,13 +99,4 @@ public class NodeStatusImpl implements NodeStatus, Serializable { return (node == null); } - - /** - * For Hibernate use - */ - @SuppressWarnings("unused") - private void setDeleted(boolean deleted) - { - // this is a convenience, derived property - } } diff --git a/source/java/org/alfresco/repo/exporter/ACPExportPackageHandler.java b/source/java/org/alfresco/repo/exporter/ACPExportPackageHandler.java index b9445318d5..64c062d765 100644 --- a/source/java/org/alfresco/repo/exporter/ACPExportPackageHandler.java +++ b/source/java/org/alfresco/repo/exporter/ACPExportPackageHandler.java @@ -23,8 +23,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.service.cmr.repository.ContentData; @@ -32,6 +30,8 @@ import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.view.ExportPackageHandler; import org.alfresco.service.cmr.view.ExporterException; import org.alfresco.util.TempFileProvider; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipOutputStream; /** @@ -54,7 +54,7 @@ public class ACPExportPackageHandler protected ZipOutputStream zipStream; protected int iFileCnt = 0; - + /** * Construct * @@ -71,7 +71,7 @@ public class ACPExportPackageHandler String zipFilePath = zipFile.getPath(); if (!zipFilePath.endsWith("." + ACP_EXTENSION)) { - zipFilePath += "." + ACP_EXTENSION; + zipFilePath += (zipFilePath.charAt(zipFilePath.length() -1) == '.') ? ACP_EXTENSION : "." + ACP_EXTENSION; } File absZipFile = new File(destDir, zipFilePath); @@ -118,6 +118,9 @@ public class ACPExportPackageHandler public void startExport() { zipStream = new ZipOutputStream(outputStream); + // NOTE: This encoding allows us to workaround bug... + // http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4820807 + zipStream.setEncoding("Cp437"); } /* (non-Javadoc) @@ -150,9 +153,9 @@ public class ACPExportPackageHandler // create zip entry for stream to export String contentDirPath = contentDir.getPath(); - if (contentDirPath.indexOf(".") != -1) + if (contentDirPath.charAt(contentDirPath.length() -1) != '.' && contentDirPath.lastIndexOf('.') != -1) { - contentDirPath = contentDirPath.substring(0, contentDirPath.indexOf(".")); + contentDirPath = contentDirPath.substring(0, contentDirPath.lastIndexOf(".")); } String extension = "bin"; if (mimetypeService != null) @@ -197,7 +200,7 @@ public class ACPExportPackageHandler String dataFilePath = dataFile.getPath(); if (!dataFilePath.endsWith(".xml")) { - dataFilePath += ".xml"; + dataFilePath += (dataFilePath .charAt(dataFilePath .length() -1) == '.') ? "xml" : ".xml"; } // add data file to zip stream diff --git a/source/java/org/alfresco/repo/exporter/ViewXMLExporter.java b/source/java/org/alfresco/repo/exporter/ViewXMLExporter.java index e7c7492ab1..a0f74e2e2b 100644 --- a/source/java/org/alfresco/repo/exporter/ViewXMLExporter.java +++ b/source/java/org/alfresco/repo/exporter/ViewXMLExporter.java @@ -532,7 +532,7 @@ import org.xml.sax.helpers.AttributesImpl; } // convert node references to paths - if (value instanceof NodeRef) + if (value instanceof NodeRef && referenceType.equals(ReferenceType.PATHREF)) { NodeRef valueNodeRef = (NodeRef)value; if (nodeRef.getStoreRef().equals(valueNodeRef.getStoreRef())) diff --git a/source/java/org/alfresco/repo/importer/ACPImportPackageHandler.java b/source/java/org/alfresco/repo/importer/ACPImportPackageHandler.java index e87e0871ae..149fba3c7e 100644 --- a/source/java/org/alfresco/repo/importer/ACPImportPackageHandler.java +++ b/source/java/org/alfresco/repo/importer/ACPImportPackageHandler.java @@ -24,11 +24,11 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.util.Enumeration; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; import org.alfresco.service.cmr.view.ImportPackageHandler; import org.alfresco.service.cmr.view.ImporterException; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipFile; /** @@ -39,7 +39,8 @@ import org.alfresco.service.cmr.view.ImporterException; public class ACPImportPackageHandler implements ImportPackageHandler { - + public final static String DEFAULT_ENCODING = "UTF-8"; + protected File file; protected ZipFile zipFile; protected String dataFileEncoding; @@ -65,7 +66,9 @@ public class ACPImportPackageHandler log("Importing from zip file " + file.getAbsolutePath()); try { - zipFile = new ZipFile(file); + // NOTE: This encoding allows us to workaround bug... + // http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4820807 + zipFile = new ZipFile(file, "Cp437"); } catch(IOException e) { @@ -86,7 +89,7 @@ public class ACPImportPackageHandler // TODO: First, locate xml meta-data file by name // Scan the zip entries one by one (the slow approach) - Enumeration entries = zipFile.entries(); + Enumeration entries = zipFile.getEntries(); while(entries.hasMoreElements()) { ZipEntry entry = (ZipEntry)entries.nextElement(); @@ -113,7 +116,7 @@ public class ACPImportPackageHandler // open the meta-data xml file InputStream dataStream = zipFile.getInputStream(xmlMetaDataEntry); - Reader inputReader = (dataFileEncoding == null) ? new InputStreamReader(dataStream) : new InputStreamReader(dataStream, dataFileEncoding); + Reader inputReader = (dataFileEncoding == null) ? new InputStreamReader(dataStream, DEFAULT_ENCODING) : new InputStreamReader(dataStream, dataFileEncoding); return new BufferedReader(inputReader); } catch(UnsupportedEncodingException e) diff --git a/source/java/org/alfresco/repo/importer/FileImportPackageHandler.java b/source/java/org/alfresco/repo/importer/FileImportPackageHandler.java index 9dfbcd61d2..704972c282 100644 --- a/source/java/org/alfresco/repo/importer/FileImportPackageHandler.java +++ b/source/java/org/alfresco/repo/importer/FileImportPackageHandler.java @@ -37,6 +37,8 @@ import org.alfresco.service.cmr.view.ImporterException; public class FileImportPackageHandler implements ImportPackageHandler { + public final static String DEFAULT_ENCODING = "UTF-8"; + protected File sourceDir; protected File dataFile; protected String dataFileEncoding; @@ -71,7 +73,7 @@ public class FileImportPackageHandler try { InputStream inputStream = new FileInputStream(dataFile); - Reader inputReader = (dataFileEncoding == null) ? new InputStreamReader(inputStream) : new InputStreamReader(inputStream, dataFileEncoding); + Reader inputReader = (dataFileEncoding == null) ? new InputStreamReader(inputStream, DEFAULT_ENCODING) : new InputStreamReader(inputStream, dataFileEncoding); return new BufferedReader(inputReader); } catch(UnsupportedEncodingException e) diff --git a/source/java/org/alfresco/repo/importer/ImporterComponent.java b/source/java/org/alfresco/repo/importer/ImporterComponent.java index 6b8690e0d6..f9535fb02d 100644 --- a/source/java/org/alfresco/repo/importer/ImporterComponent.java +++ b/source/java/org/alfresco/repo/importer/ImporterComponent.java @@ -557,9 +557,9 @@ public class ImporterComponent { importContent(nodeRef, property.getKey(), (String)objVal); } - else if (objVal instanceof List) + else if (objVal instanceof Collection) { - for (String value : (List)objVal) + for (String value : (Collection)objVal) { importContent(nodeRef, property.getKey(), value); } @@ -716,12 +716,11 @@ public class ImporterComponent if (unresolvedRef != null) { NodeRef nodeRef = resolveImportedNodeRef(importedRef.context.getNodeRef(), unresolvedRef); - if (nodeRef == null) + // TODO: Provide a better mechanism for invalid references? e.g. report warning + 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; @@ -729,11 +728,7 @@ public class ImporterComponent else { refProperty = resolveImportedNodeRef(importedRef.context.getNodeRef(), (String)importedRef.value); - if (refProperty == 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); - } + // TODO: Provide a better mechanism for invalid references? e.g. report warning } } @@ -1024,23 +1019,31 @@ public class ImporterComponent } else { - // resolve relative path - try - { - List nodeRefs = searchService.selectNodes(sourceNodeRef, importedRef, null, namespaceService, false); - if (nodeRefs.size() > 0) - { - nodeRef = nodeRefs.get(0); - } - } - catch(XPathException e) - { - nodeRef = new NodeRef(importedRef); - } - catch(AlfrescoRuntimeException e1) - { - // Note: Invalid reference format - try path search instead - } + // determine if node reference + if (NodeRef.isNodeRef(importedRef)) + { + nodeRef = new NodeRef(importedRef); + } + else + { + // resolve relative path + try + { + List nodeRefs = searchService.selectNodes(sourceNodeRef, importedRef, null, namespaceService, false); + if (nodeRefs.size() > 0) + { + nodeRef = nodeRefs.get(0); + } + } + catch(XPathException e) + { + nodeRef = new NodeRef(importedRef); + } + catch(AlfrescoRuntimeException e1) + { + // Note: Invalid reference format - try path search instead + } + } } return nodeRef; @@ -1235,7 +1238,7 @@ public class ImporterComponent NodeRef nodeRef = assocRef.getChildRef(); // Note: non-admin authorities take ownership of new nodes - if (!authorityService.hasAdminAuthority()) + if (!(authorityService.hasAdminAuthority() || authenticationService.isCurrentUserTheSystemUser())) { ownableService.takeOwnership(nodeRef); } diff --git a/source/java/org/alfresco/repo/importer/system/systeminfo.xml b/source/java/org/alfresco/repo/importer/system/systeminfo.xml index ef23080d82..c25d390bbe 100644 --- a/source/java/org/alfresco/repo/importer/system/systeminfo.xml +++ b/source/java/org/alfresco/repo/importer/system/systeminfo.xml @@ -17,7 +17,7 @@ - + diff --git a/source/java/org/alfresco/repo/importer/view/MetaDataContext.java b/source/java/org/alfresco/repo/importer/view/MetaDataContext.java index adebad55bc..8481733ec3 100644 --- a/source/java/org/alfresco/repo/importer/view/MetaDataContext.java +++ b/source/java/org/alfresco/repo/importer/view/MetaDataContext.java @@ -80,4 +80,15 @@ public class MetaDataContext extends ElementContext return properties; } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "MetaDataContext[properties=" + properties.size() + "]"; + } + + } diff --git a/source/java/org/alfresco/repo/importer/view/NodeItemContext.java b/source/java/org/alfresco/repo/importer/view/NodeItemContext.java index f43dcff6ff..251ab91c43 100644 --- a/source/java/org/alfresco/repo/importer/view/NodeItemContext.java +++ b/source/java/org/alfresco/repo/importer/view/NodeItemContext.java @@ -49,4 +49,15 @@ public class NodeItemContext extends ElementContext { return nodeContext; } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "NodeItemContext[nodeContext=" + nodeContext.toString() + "]"; + } + + } diff --git a/source/java/org/alfresco/repo/importer/view/ViewParser.java b/source/java/org/alfresco/repo/importer/view/ViewParser.java index 850a6dd2f4..b3146ceae0 100644 --- a/source/java/org/alfresco/repo/importer/view/ViewParser.java +++ b/source/java/org/alfresco/repo/importer/view/ViewParser.java @@ -197,7 +197,11 @@ public class ViewParser implements Parser // Handle special view directives if (defName.equals(VIEW_METADATA)) { - parserContext.elementStack.push(new MetaDataContext(defName, (ElementContext)element)); + MetaDataContext metaDataContext = new MetaDataContext(defName, (ElementContext)element); + parserContext.elementStack.push(metaDataContext); + + if (logger.isDebugEnabled()) + logger.debug(indentLog("Pushed " + metaDataContext, parserContext.elementStack.size() -1)); } else if (defName.equals(VIEW_ASPECTS) || defName.equals(VIEW_PROPERTIES) || defName.equals(VIEW_ASSOCIATIONS) || defName.equals(VIEW_ACL)) { @@ -210,7 +214,11 @@ public class ViewParser implements Parser throw new ImporterException("Element " + defName + " can only be declared within a node"); } NodeContext node = (NodeContext)element; - parserContext.elementStack.push(new NodeItemContext(defName, node)); + NodeItemContext nodeItemContext = new NodeItemContext(defName, node); + parserContext.elementStack.push(nodeItemContext); + + if (logger.isDebugEnabled()) + logger.debug(indentLog("Pushed " + nodeItemContext, parserContext.elementStack.size() -1)); // process ACL specific attributes if (defName.equals(VIEW_ACL)) diff --git a/source/java/org/alfresco/repo/jscript/RhinoScriptService.java b/source/java/org/alfresco/repo/jscript/RhinoScriptService.java index ce716e433e..96f880aafa 100644 --- a/source/java/org/alfresco/repo/jscript/RhinoScriptService.java +++ b/source/java/org/alfresco/repo/jscript/RhinoScriptService.java @@ -36,6 +36,7 @@ import org.alfresco.service.cmr.repository.ScriptService; import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.namespace.QName; import org.mozilla.javascript.Context; +import org.mozilla.javascript.ImporterTopLevel; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; @@ -197,8 +198,11 @@ public class RhinoScriptService implements ScriptService { // The easiest way to embed Rhino is just to create a new scope this way whenever // you need one. However, initStandardObjects is an expensive method to call and it - // allocates a fair amount of memory. + // allocates a fair amount of memory. ImporterTopLevel provides a scope allowing + // the import of java classes and packages. + Scriptable topLevelScope = new ImporterTopLevel(cx); Scriptable scope = cx.initStandardObjects(); + scope.setParentScope(topLevelScope); // insert supplied object model into root of the default scope if (model != null) diff --git a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java index 7e5be748d2..441fbbfd4a 100644 --- a/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java +++ b/source/java/org/alfresco/repo/node/BaseNodeServiceTest.java @@ -156,7 +156,7 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest // create a first store directly StoreRef storeRef = nodeService.createStore( StoreRef.PROTOCOL_WORKSPACE, - "Test_" + System.nanoTime()); + "Test_" + System.currentTimeMillis()); rootNodeRef = nodeService.getRootNode(storeRef); } @@ -622,6 +622,36 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest nodeService.hasAspect(nodeRef, ASPECT_QNAME_TEST_TITLED)); } + public void testCascadeDelete() throws Exception + { + // build the node and commit the node graph + Map assocRefs = buildNodeGraph(nodeService, rootNodeRef); + NodeRef n3Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n1_p_n3")).getChildRef(); + NodeRef n4Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n2_p_n4")).getChildRef(); + NodeRef n6Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n3_p_n6")).getChildRef(); + NodeRef n7Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n5_p_n7")).getChildRef(); + NodeRef n8Ref = assocRefs.get(QName.createQName(BaseNodeServiceTest.NAMESPACE, "n6_p_n8")).getChildRef(); + + // control checks + assertEquals("n6 not present", 1, countNodesByReference(n6Ref)); + assertEquals("n8 not present", 1, countNodesByReference(n8Ref)); + assertEquals("n6 primary parent association not present on n3", 1, countChildrenOfNode(n3Ref)); + assertEquals("n6 secondary parent association not present on n4", 1, countChildrenOfNode(n4Ref)); + assertEquals("n8 secondary parent association not present on n7", 1, countChildrenOfNode(n7Ref)); + + // delete n6 + nodeService.deleteNode(n6Ref); + // commit to check + setComplete(); + endTransaction(); + + assertEquals("n6 not directly deleted", 0, countNodesByReference(n6Ref)); + assertEquals("n8 not cascade deleted", 0, countNodesByReference(n8Ref)); + assertEquals("n6 primary parent association not removed from n3", 0, countChildrenOfNode(n3Ref)); + assertEquals("n6 secondary parent association not removed from n4", 0, countChildrenOfNode(n4Ref)); + assertEquals("n8 secondary parent association not removed from n7", 0, countChildrenOfNode(n7Ref)); + } + public static class BadOnDeleteNodePolicy implements NodeServicePolicies.OnDeleteNodePolicy, NodeServicePolicies.BeforeDeleteNodePolicy @@ -703,10 +733,12 @@ public abstract class BaseNodeServiceTest extends BaseSpringTest "select node.childAssocs" + " from " + NodeImpl.class.getName() + " node" + - " where node.uuid = ?"; + " where node.uuid = ? and node.store.key.protocol = ? and node.store.key.identifier = ?"; Session session = getSession(); List results = session.createQuery(query) .setString(0, nodeRef.getId()) + .setString(1, nodeRef.getStoreRef().getProtocol()) + .setString(2, nodeRef.getStoreRef().getIdentifier()) .list(); int count = results.size(); return count; diff --git a/source/java/org/alfresco/repo/node/index/FullIndexRecoveryComponent.java b/source/java/org/alfresco/repo/node/index/FullIndexRecoveryComponent.java index 41ec62b5e5..3000634953 100644 --- a/source/java/org/alfresco/repo/node/index/FullIndexRecoveryComponent.java +++ b/source/java/org/alfresco/repo/node/index/FullIndexRecoveryComponent.java @@ -80,6 +80,7 @@ public class FullIndexRecoveryComponent extends HibernateDaoSupport implements I { public static final String QUERY_GET_NEXT_CHANGE_TXN_IDS = "node.GetNextChangeTxnIds"; public static final String QUERY_GET_CHANGED_NODE_STATUSES = "node.GetChangedNodeStatuses"; + public static final String QUERY_GET_DELETED_NODE_STATUSES = "node.GetDeletedNodeStatuses"; public static final String QUERY_GET_CHANGED_NODE_STATUSES_COUNT = "node.GetChangedNodeStatusesCount"; private static final String START_TXN_ID = "000"; @@ -705,8 +706,7 @@ public class FullIndexRecoveryComponent extends HibernateDaoSupport implements I public Object doInHibernate(Session session) { Query query = session.getNamedQuery(QUERY_GET_CHANGED_NODE_STATUSES_COUNT); - query.setBoolean("deleted", false) - .setString("storeProtocol", storeRef.getProtocol()) + query.setString("storeProtocol", storeRef.getProtocol()) .setString("storeIdentifier", storeRef.getIdentifier()) .setString("changeTxnId", changeTxnId) .setReadOnly(true); @@ -726,8 +726,7 @@ public class FullIndexRecoveryComponent extends HibernateDaoSupport implements I public Object doInHibernate(Session session) { Query query = session.getNamedQuery(QUERY_GET_CHANGED_NODE_STATUSES); - query.setBoolean("deleted", false) - .setString("storeProtocol", storeRef.getProtocol()) + query.setString("storeProtocol", storeRef.getProtocol()) .setString("storeIdentifier", storeRef.getIdentifier()) .setString("changeTxnId", changeTxnId) .setReadOnly(true); @@ -746,9 +745,8 @@ public class FullIndexRecoveryComponent extends HibernateDaoSupport implements I { public Object doInHibernate(Session session) { - Query query = session.getNamedQuery(QUERY_GET_CHANGED_NODE_STATUSES); - query.setBoolean("deleted", true) - .setString("storeProtocol", storeRef.getProtocol()) + Query query = session.getNamedQuery(QUERY_GET_DELETED_NODE_STATUSES); + query.setString("storeProtocol", storeRef.getProtocol()) .setString("storeIdentifier", storeRef.getIdentifier()) .setString("changeTxnId", changeTxnId) .setReadOnly(true); diff --git a/source/java/org/alfresco/repo/search/SearcherComponentTest.java b/source/java/org/alfresco/repo/search/SearcherComponentTest.java index c366bef2b3..d83f3d60b1 100644 --- a/source/java/org/alfresco/repo/search/SearcherComponentTest.java +++ b/source/java/org/alfresco/repo/search/SearcherComponentTest.java @@ -289,7 +289,7 @@ public class SearcherComponentTest extends TestCase /** * Tests the like and contains functions (FTS functions) within a currently executing transaction */ - public void testLikeAndContains() throws Exception + public void xtestLikeAndContains() throws Exception { Map assocRefs = BaseNodeServiceTest.buildNodeGraph(nodeService, rootNodeRef); diff --git a/source/java/org/alfresco/repo/security/authentication/ldap/LDAPGroupExportSource.java b/source/java/org/alfresco/repo/security/authentication/ldap/LDAPGroupExportSource.java index 013760b20e..a52fc2c438 100644 --- a/source/java/org/alfresco/repo/security/authentication/ldap/LDAPGroupExportSource.java +++ b/source/java/org/alfresco/repo/security/authentication/ldap/LDAPGroupExportSource.java @@ -280,6 +280,23 @@ public class LDAPGroupExportSource implements ExportSource, InitializingBean ContentModel.TYPE_AUTHORITY_CONTAINER.getLocalName(), ContentModel.TYPE_AUTHORITY_CONTAINER .toPrefixString(namespaceService), attrs); + if ((authorityDAO != null ) && authorityDAO.authorityExists(group.gid)) + { + NodeRef authNodeRef = authorityDAO.getAuthorityNodeRefOrNull(group.gid); + if (authNodeRef != null) + { + String uguid = authorityDAO.getAuthorityNodeRefOrNull(group.gid).getId(); + + writer.startElement(nodeUUID.getNamespaceURI(), nodeUUID.getLocalName(), nodeUUID + .toPrefixString(namespaceService), new AttributesImpl()); + + writer.characters(uguid.toCharArray(), 0, uguid.length()); + + writer.endElement(nodeUUID.getNamespaceURI(), nodeUUID.getLocalName(), nodeUUID + .toPrefixString(namespaceService)); + } + } + writer.startElement(ContentModel.PROP_AUTHORITY_NAME.getNamespaceURI(), ContentModel.PROP_AUTHORITY_NAME .getLocalName(), ContentModel.PROP_AUTHORITY_NAME.toPrefixString(namespaceService), new AttributesImpl()); diff --git a/source/java/org/alfresco/service/cmr/repository/NodeRef.java b/source/java/org/alfresco/service/cmr/repository/NodeRef.java index 3f2eb2736f..f16b838003 100644 --- a/source/java/org/alfresco/service/cmr/repository/NodeRef.java +++ b/source/java/org/alfresco/service/cmr/repository/NodeRef.java @@ -17,6 +17,8 @@ package org.alfresco.service.cmr.repository; import java.io.Serializable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.alfresco.error.AlfrescoRuntimeException; @@ -27,9 +29,9 @@ import org.alfresco.error.AlfrescoRuntimeException; */ public final class NodeRef implements EntityRef, Serializable { - private static final long serialVersionUID = 3760844584074227768L; private static final String URI_FILLER = "/"; + private static final Pattern nodeRefPattern = Pattern.compile(".+://.+/.+"); private final StoreRef storeRef; private final String id; @@ -44,8 +46,7 @@ public final class NodeRef implements EntityRef, Serializable { if (storeRef == null) { - throw new IllegalArgumentException( - "Store reference may not be null"); + throw new IllegalArgumentException("Store reference may not be null"); } if (id == null) { @@ -128,6 +129,18 @@ public final class NodeRef implements EntityRef, Serializable return id; } + /** + * Determine if passed string conforms to the pattern of a node reference + * + * @param nodeRef the node reference as a string + * @return true => it matches the pattern of a node reference + */ + public static boolean isNodeRef(String nodeRef) + { + Matcher matcher = nodeRefPattern.matcher(nodeRef); + return matcher.matches(); + } + /** * Helper class to convey the status of a node. * diff --git a/source/java/org/alfresco/service/cmr/repository/NodeRefTest.java b/source/java/org/alfresco/service/cmr/repository/NodeRefTest.java index 370094105c..8633210653 100644 --- a/source/java/org/alfresco/service/cmr/repository/NodeRefTest.java +++ b/source/java/org/alfresco/service/cmr/repository/NodeRefTest.java @@ -50,4 +50,13 @@ public class NodeRefTest extends TestCase NodeRef nodeRef2 = new NodeRef(storeRef, "456"); assertEquals("equals failure", nodeRef, nodeRef2); } + + public void testNodeRefPattern() throws Exception + { + StoreRef storeRef = new StoreRef("ABC", "123"); + NodeRef nodeRef = new NodeRef(storeRef, "456"); + + assertTrue(NodeRef.isNodeRef(nodeRef.toString())); + assertFalse(NodeRef.isNodeRef("sdfsdf:sdfsdf")); + } } diff --git a/source/java/org/alfresco/service/cmr/repository/TemplateNode.java b/source/java/org/alfresco/service/cmr/repository/TemplateNode.java index 70993b26e3..c9b64e52a4 100644 --- a/source/java/org/alfresco/service/cmr/repository/TemplateNode.java +++ b/source/java/org/alfresco/service/cmr/repository/TemplateNode.java @@ -502,6 +502,14 @@ public final class TemplateNode implements Serializable return this.permissions; } + /** + * @return true if this node inherits permissions from its parent node, false otherwise. + */ + public boolean getInheritsPermissions() + { + return this.services.getPermissionService().getInheritParentPermissions(this.nodeRef); + } + /** * @return the parent node */ diff --git a/source/java/org/alfresco/tools/Export.java b/source/java/org/alfresco/tools/Export.java index 25e737a355..4f28271d48 100644 --- a/source/java/org/alfresco/tools/Export.java +++ b/source/java/org/alfresco/tools/Export.java @@ -60,7 +60,7 @@ public final class Export extends Tool /* (non-Javadoc) * @see org.alfresco.tools.Tool#getToolName() */ - @Override + protected @Override String getToolName() { return "Alfresco Repository Exporter"; @@ -72,7 +72,7 @@ public final class Export extends Tool * @param args the arguments * @return the export context */ - @Override + protected @Override /*package*/ ToolContext processArgs(String[] args) { context = new ExportContext(); @@ -91,7 +91,7 @@ public final class Export extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the parameter -store must be specified"); + throw new ToolArgumentException("The value for the parameter -store must be specified"); } context.storeRef = new StoreRef(args[i]); } @@ -100,7 +100,7 @@ public final class Export extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the parameter -path must be specified"); + throw new ToolArgumentException("The value for the parameter -path must be specified"); } context.path = args[i]; } @@ -109,7 +109,7 @@ public final class Export extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the parameter -dir must be specified"); + throw new ToolArgumentException("The value for the parameter -dir must be specified"); } context.destDir = args[i]; } @@ -118,7 +118,7 @@ public final class Export extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the parameter -packagedir must be specified"); + throw new ToolArgumentException("The value for the parameter -packagedir must be specified"); } context.packageDir = args[i]; } @@ -127,7 +127,7 @@ public final class Export extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -user must be specified"); + throw new ToolArgumentException("The value for the option -user must be specified"); } context.setUsername(args[i]); } @@ -136,7 +136,7 @@ public final class Export extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -pwd must be specified"); + throw new ToolArgumentException("The value for the option -pwd must be specified"); } context.setPassword(args[i]); } @@ -170,7 +170,7 @@ public final class Export extends Tool } else { - throw new ToolException("Unknown option " + args[i]); + throw new ToolArgumentException("Unknown option " + args[i]); } // next argument @@ -183,34 +183,35 @@ public final class Export extends Tool /* (non-Javadoc) * @see org.alfresco.tools.Tool#displayHelp() */ - @Override + protected @Override /*package*/ void displayHelp() { - System.out.println("Usage: export -user username -s[tore] store [options] packagename"); - System.out.println(""); - System.out.println("username: username for login"); - System.out.println("store: the store to extract from in the form of scheme://store_name"); - System.out.println("packagename: the filename to export to (with or without extension)"); - System.out.println(""); - System.out.println("Options:"); - System.out.println(" -h[elp] display this help"); - System.out.println(" -p[ath] the path within the store to extract from (default: /)"); - System.out.println(" -d[ir] the destination directory to export to (default: current directory)"); - System.out.println(" -pwd password for login"); - System.out.println(" -packagedir the directory to place extracted content (default: dir/)"); - System.out.println(" -root extract the item located at export path"); - System.out.println(" -nochildren do not extract children of the item at export path"); - System.out.println(" -overwrite force overwrite of existing export package if it already exists"); - System.out.println(" -quiet do not display any messages during export"); - System.out.println(" -verbose report export progress"); - System.out.println(" -zip export in zip format"); + logError("Usage: export -user username -s[tore] store [options] packagename"); + logError(""); + logError("username: username for login"); + logError("store: the store to extract from in the form of scheme://store_name"); + logError("packagename: the filename to export to (with or without extension)"); + logError(""); + logError("Options:"); + logError(" -h[elp] display this help"); + logError(" -p[ath] the path within the store to extract from (default: /)"); + logError(" -d[ir] the destination directory to export to (default: current directory)"); + logError(" -pwd password for login"); + logError(" -packagedir the directory to place extracted content (default: dir/)"); + logError(" -root extract the item located at export path"); + logError(" -nochildren do not extract children of the item at export path"); + logError(" -overwrite force overwrite of existing export package if it already exists"); + logError(" -quiet do not display any messages during export"); + logError(" -verbose report export progress"); + logError(" -zip export in zip format"); } /* (non-Javadoc) * @see org.alfresco.tools.Tool#execute() */ - @Override - void execute() throws ToolException + protected @Override + /*package*/ int execute() + throws ToolException { ExporterService exporter = getServiceRegistry().getExporterService(); MimetypeService mimetypeService = getServiceRegistry().getMimetypeService(); @@ -238,9 +239,10 @@ public final class Export extends Tool } catch(ExporterException e) { - e.printStackTrace(); throw new ToolException("Failed to export", e); } + + return 0; } /** @@ -270,7 +272,7 @@ public final class Export extends Tool */ protected void log(String message) { - Export.this.log(message); + Export.this.logInfo(message); } } @@ -301,7 +303,7 @@ public final class Export extends Tool */ protected void log(String message) { - Export.this.log(message); + Export.this.logInfo(message); } } @@ -341,18 +343,18 @@ public final class Export extends Tool if (storeRef == null) { - throw new ToolException("Store to export from has not been specified."); + throw new ToolArgumentException("Store to export from has not been specified."); } if (packageName == null) { - throw new ToolException("Package name has not been specified."); + throw new ToolArgumentException("Package name has not been specified."); } if (destDir != null) { File fileDestDir = new File(destDir); if (fileDestDir.exists() == false) { - throw new ToolException("Destination directory " + fileDestDir.getAbsolutePath() + " does not exist."); + throw new ToolArgumentException("Destination directory " + fileDestDir.getAbsolutePath() + " does not exist."); } } } @@ -612,7 +614,7 @@ public final class Export extends Tool */ public void warning(String warning) { - log("Warning: " + warning); + logInfo("Warning: " + warning); } /* (non-Javadoc) diff --git a/source/java/org/alfresco/tools/Import.java b/source/java/org/alfresco/tools/Import.java index d79393eb70..db2f1837d6 100644 --- a/source/java/org/alfresco/tools/Import.java +++ b/source/java/org/alfresco/tools/Import.java @@ -61,8 +61,9 @@ public class Import extends Tool /* (non-Javadoc) * @see org.alfresco.tools.Tool#processArgs(java.lang.String[]) */ - @Override + protected @Override /*package*/ ToolContext processArgs(String[] args) + throws ToolArgumentException { context = new ImportContext(); context.setLogin(true); @@ -80,7 +81,7 @@ public class Import extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -store must be specified"); + throw new ToolArgumentException("The value for the option -store must be specified"); } context.storeRef = new StoreRef(args[i]); } @@ -89,7 +90,7 @@ public class Import extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -path must be specified"); + throw new ToolArgumentException("The value for the option -path must be specified"); } context.path = args[i]; } @@ -98,7 +99,7 @@ public class Import extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -dir must be specified"); + throw new ToolArgumentException("The value for the option -dir must be specified"); } context.sourceDir = args[i]; } @@ -107,7 +108,7 @@ public class Import extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -user must be specified"); + throw new ToolArgumentException("The value for the option -user must be specified"); } context.setUsername(args[i]); } @@ -116,7 +117,7 @@ public class Import extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -pwd must be specified"); + throw new ToolArgumentException("The value for the option -pwd must be specified"); } context.setPassword(args[i]); } @@ -125,7 +126,7 @@ public class Import extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -encoding must be specified"); + throw new ToolArgumentException("The value for the option -encoding must be specified"); } context.encoding = args[i]; } @@ -138,7 +139,7 @@ public class Import extends Tool } catch(IllegalArgumentException e) { - throw new ToolException("The value " + args[i] + " is an invalid uuidBinding"); + throw new ToolArgumentException("The value " + args[i] + " is an invalid uuidBinding"); } } else if (args[i].equals("-quiet")) @@ -155,7 +156,7 @@ public class Import extends Tool } else { - throw new ToolException("Unknown option " + args[i]); + throw new ToolArgumentException("Unknown option " + args[i]); } // next argument @@ -168,30 +169,30 @@ public class Import extends Tool /* (non-Javadoc) * @see org.alfresco.tools.Tool#displayHelp() */ - @Override + protected @Override /*package*/ void displayHelp() { - System.out.println("Usage: import -user username -s[tore] store [options] packagename"); - System.out.println(""); - System.out.println("username: username for login"); - System.out.println("store: the store to import into the form of scheme://store_name"); - System.out.println("packagename: the filename to import from (with or without extension)"); - System.out.println(""); - System.out.println("Options:"); - System.out.println(" -h[elp] display this help"); - System.out.println(" -p[ath] the path within the store to extract into (default: /)"); - System.out.println(" -d[ir] the source directory to import from (default: current directory)"); - System.out.println(" -pwd password for login"); - System.out.println(" -encoding package file encoding (default: " + Charset.defaultCharset() + ")"); - System.out.println(" -uuidBinding CREATE_NEW, REMOVE_EXISTING, REPLACE_EXISTING, UPDATE_EXISTING, THROW_ON_COLLISION (default: CREATE_NEW)"); - System.out.println(" -quiet do not display any messages during import"); - System.out.println(" -verbose report import progress"); + logError("Usage: import -user username -s[tore] store [options] packagename"); + logError(""); + logError("username: username for login"); + logError("store: the store to import into the form of scheme://store_name"); + logError("packagename: the filename to import from (with or without extension)"); + logError(""); + logError("Options:"); + logError(" -h[elp] display this help"); + logError(" -p[ath] the path within the store to extract into (default: /)"); + logError(" -d[ir] the source directory to import from (default: current directory)"); + logError(" -pwd password for login"); + logError(" -encoding package file encoding (default: " + Charset.defaultCharset() + ")"); + logError(" -uuidBinding CREATE_NEW, REMOVE_EXISTING, REPLACE_EXISTING, UPDATE_EXISTING, THROW_ON_COLLISION (default: CREATE_NEW)"); + logError(" -quiet do not display any messages during import"); + logError(" -verbose report import progress"); } /* (non-Javadoc) * @see org.alfresco.tools.Tool#getToolName() */ - @Override + protected @Override /*package*/ String getToolName() { return "Alfresco Repository Importer"; @@ -200,8 +201,8 @@ public class Import extends Tool /* (non-Javadoc) * @see org.alfresco.tools.Tool#execute() */ - @Override - /*package*/ void execute() throws ToolException + protected @Override + /*package*/ int execute() throws ToolException { ImporterService importer = getServiceRegistry().getImporterService(); @@ -225,6 +226,8 @@ public class Import extends Tool { throw new ToolException("Failed to import package due to " + e.getMessage(), e); } + + return 0; } /** @@ -253,7 +256,7 @@ public class Import extends Tool */ protected void log(String message) { - Import.this.log(message); + Import.this.logInfo(message); } } @@ -283,7 +286,7 @@ public class Import extends Tool */ protected void log(String message) { - Import.this.log(message); + Import.this.logInfo(message); } } @@ -392,18 +395,18 @@ public class Import extends Tool if (storeRef == null) { - throw new ToolException("Store to import into has not been specified."); + throw new ToolArgumentException("Store to import into has not been specified."); } if (packageName == null) { - throw new ToolException("Package name has not been specified."); + throw new ToolArgumentException("Package name has not been specified."); } if (sourceDir != null) { File fileSourceDir = getSourceDir(); if (fileSourceDir.exists() == false) { - throw new ToolException("Source directory " + fileSourceDir.getAbsolutePath() + " does not exist."); + throw new ToolArgumentException("Source directory " + fileSourceDir.getAbsolutePath() + " does not exist."); } } if (packageName.endsWith(".acp")) @@ -411,7 +414,7 @@ public class Import extends Tool File packageFile = new File(getSourceDir(), packageName); if (!packageFile.exists()) { - throw new ToolException("Package zip file " + packageFile.getAbsolutePath() + " does not exist."); + throw new ToolArgumentException("Package zip file " + packageFile.getAbsolutePath() + " does not exist."); } zipFile = true; } @@ -420,7 +423,7 @@ public class Import extends Tool File packageFile = new File(getSourceDir(), getDataFile().getPath()); if (!packageFile.exists()) { - throw new ToolException("Package file " + packageFile.getAbsolutePath() + " does not exist."); + throw new ToolArgumentException("Package file " + packageFile.getAbsolutePath() + " does not exist."); } } } diff --git a/source/java/org/alfresco/tools/Repository.java b/source/java/org/alfresco/tools/Repository.java index 4cadae3e9d..ce6c960fe3 100644 --- a/source/java/org/alfresco/tools/Repository.java +++ b/source/java/org/alfresco/tools/Repository.java @@ -26,13 +26,13 @@ import java.io.IOException; */ public class Repository extends Tool { - @Override + protected @Override String getToolName() { return "Repository"; } - @Override + protected @Override ToolContext processArgs(String[] args) throws ToolException { ToolContext context = new ToolContext(); @@ -51,7 +51,7 @@ public class Repository extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -user must be specified"); + throw new ToolArgumentException("The value for the option -user must be specified"); } context.setUsername(args[i]); } @@ -60,13 +60,13 @@ public class Repository extends Tool i++; if (i == args.length || args[i].length() == 0) { - throw new ToolException("The value for the option -pwd must be specified"); + throw new ToolArgumentException("The value for the option -pwd must be specified"); } context.setPassword(args[i]); } else { - throw new ToolException("Unknown option " + args[i] + ". Use -help for options."); + throw new ToolArgumentException("Unknown option " + args[i] + ". Use -help for options."); } // next argument @@ -76,10 +76,10 @@ public class Repository extends Tool return context; } - @Override + protected @Override void displayHelp() { - System.out.println( + logError( "usage: repository [OPTIONS] \n" + "\n" + "Initialize the Alfresco application context, initiating any \n" + @@ -92,7 +92,7 @@ public class Repository extends Tool } @Override - synchronized void execute() throws ToolException + protected synchronized int execute() throws ToolException { try { @@ -107,6 +107,8 @@ public class Repository extends Tool { // just ignore } + + return 0; } /** diff --git a/source/java/org/alfresco/tools/Tool.java b/source/java/org/alfresco/tools/Tool.java index 80a56c90e9..903dd9a97f 100644 --- a/source/java/org/alfresco/tools/Tool.java +++ b/source/java/org/alfresco/tools/Tool.java @@ -16,6 +16,9 @@ */ package org.alfresco.tools; +import java.io.PrintWriter; +import java.io.StringWriter; + import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.util.ApplicationContextHelper; @@ -44,8 +47,8 @@ public abstract class Tool * @return the tool context * @throws ToolException */ - /*package*/ ToolContext processArgs(String[] args) - throws ToolException + protected ToolContext processArgs(String[] args) + throws ToolArgumentException { return new ToolContext(); } @@ -53,9 +56,9 @@ public abstract class Tool /** * Display Tool Help */ - /*package*/ void displayHelp() + protected void displayHelp() { - System.out.println("Sorry. Help is not available."); + logError("Sorry. Help is not available."); } /** @@ -63,7 +66,7 @@ public abstract class Tool * * @throws ToolException */ - /*package*/ abstract void execute() + protected abstract int execute() throws ToolException; /** @@ -71,34 +74,14 @@ public abstract class Tool * * @return the tool name */ - /*package*/ abstract String getToolName(); + protected abstract String getToolName(); - /** - * Get the Application Context - * - * @return the application context - */ - /*package*/ final ApplicationContext getApplicationContext() - { - return appContext; - } - - /** - * Get the Repository Service Registry - * - * @return the service registry - */ - /*package*/ final ServiceRegistry getServiceRegistry() - { - return serviceRegistry; - } - /** * Log message * * @param msg message to log */ - /*package*/ final void log(String msg) + protected void logInfo(String msg) { if (toolContext.isQuiet() == false) { @@ -111,65 +94,124 @@ public abstract class Tool * * @param msg message to log */ - /*package*/ final void logVerbose(String msg) + protected void logVerbose(String msg) { if (toolContext.isVerbose()) { - log(msg); + logInfo(msg); } } + /** + * Log Error message + * + * @param msg message to log + */ + protected void logError(String msg) + { + System.out.println(msg); + } + + /** + * Handle Error Message + * + * @param e exception + */ + protected int handleError(Throwable e) + { + if (e instanceof ToolArgumentException) + { + logError(e.getMessage()); + logError(""); + displayHelp(); + } + else if (e instanceof ToolException) + { + logError(e.getMessage()); + } + else + { + logError("The following error has occurred:"); + logError(e.getMessage()); + if (toolContext != null && toolContext.isVerbose()) + { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + e.printStackTrace(printWriter); + logError(stringWriter.toString()); + } + } + + // return generic error code + return -1; + } + + /** + * Exit Tool + * + * @param status status code + */ + protected void exit(int status) + { + System.exit(status); + } + + /** + * Get the Application Context + * + * @return the application context + */ + protected final ApplicationContext getApplicationContext() + { + return appContext; + } + + /** + * Get the Repository Service Registry + * + * @return the service registry + */ + protected final ServiceRegistry getServiceRegistry() + { + return serviceRegistry; + } + /** * Tool entry point * * @param args the tool arguments */ - /*package*/ final void start(String[] args) + public final void start(String[] args) { + int status = -1; + try { // Process tool arguments toolContext = processArgs(args); toolContext.validate(); - try + if (toolContext.isHelp()) { - if (toolContext.isHelp()) - { - // Display help, if requested - displayHelp(); - } - else - { - // Perform Tool behaviour - log(getToolName()); - initialiseRepository(); - login(); - execute(); - log(getToolName() + " successfully completed."); - } - System.exit(0); + // Display help, if requested + displayHelp(); } - catch (ToolException e) + else { - displayError(e); - System.exit(-1); + // Perform Tool behaviour + logInfo(getToolName()); + initialiseRepository(); + login(); + status = execute(); + logInfo(getToolName() + " successfully completed."); } } - catch(ToolException e) - { - System.out.println(e.getMessage()); - System.out.println(); - displayHelp(); - System.exit(-1); - } catch (Throwable e) { - System.out.println("The following error has occurred:"); - System.out.println(e.getMessage()); - e.printStackTrace(); - System.exit(-1); + status = handleError(e); } + + exit(status); } /** @@ -180,7 +222,7 @@ public abstract class Tool // TODO: Replace with call to ServiceRegistry AuthenticationService auth = (AuthenticationService) serviceRegistry.getAuthenticationService(); auth.authenticate(toolContext.getUsername(), toolContext.getPassword().toCharArray()); - log("Connected as " + toolContext.getUsername()); + logInfo("Connected as " + toolContext.getUsername()); } /** @@ -192,18 +234,4 @@ public abstract class Tool serviceRegistry = (ServiceRegistry) appContext.getBean(ServiceRegistry.SERVICE_REGISTRY); } - /** - * Display Error Message - * - * @param e exception - */ - private void displayError(Throwable e) - { - System.out.println(e.getMessage()); - if (toolContext != null && toolContext.isVerbose()) - { - e.printStackTrace(); - } - } - } diff --git a/source/java/org/alfresco/tools/ToolArgumentException.java b/source/java/org/alfresco/tools/ToolArgumentException.java new file mode 100644 index 0000000000..62a661c42a --- /dev/null +++ b/source/java/org/alfresco/tools/ToolArgumentException.java @@ -0,0 +1,38 @@ +/* + * 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.tools; + +/** + * Tool Argument Exception + * + * @author David Caruana + */ +/*package*/ class ToolArgumentException extends ToolException +{ + private static final long serialVersionUID = 3880274996297222647L; + + /*package*/ ToolArgumentException(String msg) + { + super(msg); + } + + /*package*/ ToolArgumentException(String msg, Throwable cause) + { + super(msg, cause); + } + +} diff --git a/source/java/org/alfresco/tools/ToolContext.java b/source/java/org/alfresco/tools/ToolContext.java index eba38883d9..2ab796b67a 100644 --- a/source/java/org/alfresco/tools/ToolContext.java +++ b/source/java/org/alfresco/tools/ToolContext.java @@ -162,7 +162,7 @@ package org.alfresco.tools; * Validate Tool Context */ /*package*/ void validate() - throws ToolException + throws ToolArgumentException { if (login) { diff --git a/source/java/org/alfresco/util/ISO9075.java b/source/java/org/alfresco/util/ISO9075.java index a5da8d8b52..caf65ae9e6 100644 --- a/source/java/org/alfresco/util/ISO9075.java +++ b/source/java/org/alfresco/util/ISO9075.java @@ -174,7 +174,7 @@ public class ISO9075 if (matchesEncodedPattern(toDecode, i)) { decoded.append(((char) Integer.parseInt(toDecode.substring(i + 2, i + 6), 16))); - i += 6; + i += 6;// then one added for the loop to mkae the length of 7 } else { diff --git a/source/java/org/alfresco/util/ISO9075Test.java b/source/java/org/alfresco/util/ISO9075Test.java index e23cfb3a44..fa766ba924 100644 --- a/source/java/org/alfresco/util/ISO9075Test.java +++ b/source/java/org/alfresco/util/ISO9075Test.java @@ -33,7 +33,7 @@ public class ISO9075Test extends TestCase public void testEncoding() { - assertEquals("MyDocuments", ISO9075.encode("MyDocuments")); + assertEquals("My2Documents", ISO9075.encode("My2Documents")); assertEquals("My_x002f_Documents", ISO9075.encode("My/Documents")); assertEquals("My_Documents", ISO9075.encode("My_Documents")); assertEquals("My_x0020_Documents", ISO9075.encode("My Documents")); @@ -46,7 +46,8 @@ public class ISO9075Test extends TestCase assertEquals( "_x0020__x0060__x00ac__x00a6__x0021__x0022__x00a3__x0024__x0025__x005e__x0026__x002a__x0028__x0029_-__x003d__x002b__x0009__x000a__x005c__x0000__x005b__x005d__x007b__x007d__x003b__x0027__x0023__x003a__x0040__x007e__x002c_._x002f__x003c__x003e__x003f__x005c__x007c_", ISO9075.encode(" `\u00ac\u00a6!\"\u00a3$%^&*()-_=+\t\n\\\u0000[]{};'#:@~,./<>?\\|")); - assertEquals("\u0123_x4567_\u8900_xabcd__xefff__xT65A_", ISO9075.encode("\u0123\u4567\u8900\uabcd\uefff_xT65A_")); + assertEquals("\u0123_x4567_\u8900_xabcd__xefff__xT65A_", ISO9075 + .encode("\u0123\u4567\u8900\uabcd\uefff_xT65A_")); assertEquals("_x003a_", ISO9075.encode(":")); } @@ -67,7 +68,46 @@ public class ISO9075Test extends TestCase " `\u00ac\u00a6!\"\u00a3$%^&*()-_=+\t\n\\\u0000[]{};'#:@~,./<>?\\|", ISO9075 .decode("_x0020__x0060__x00ac__x00a6__x0021__x0022__x00a3__x0024__x0025__x005e__x0026__x002a__x0028__x0029_-__x003d__x002b__x0009__x000a__x005c__x0000__x005b__x005d__x007b__x007d__x003b__x0027__x0023__x003a__x0040__x007e__x002c_._x002f__x003c__x003e__x003f__x005c__x007c_")); - assertEquals("\u0123\u4567\u8900\uabcd\uefff_xT65A_", ISO9075.decode("\u0123_x4567_\u8900_xabcd__xefff__xT65A_")); + assertEquals("\u0123\u4567\u8900\uabcd\uefff_xT65A_", ISO9075 + .decode("\u0123_x4567_\u8900_xabcd__xefff__xT65A_")); + } + + public void testRoundTrip1() + { + assertEquals("MyDocuments", ISO9075.decode(ISO9075.encode("MyDocuments"))); + assertEquals("My_Documents", ISO9075.decode(ISO9075.encode("My_Documents"))); + assertEquals("My Documents", ISO9075.decode(ISO9075.encode("My Documents"))); + assertEquals("My_x0020Documents", ISO9075.decode(ISO9075.encode("My_x0020Documents"))); + assertEquals("My_x0020_Documents", ISO9075.decode(ISO9075.encode("My_x0020_Documents"))); + assertEquals("_x0020_Documents", ISO9075.decode(ISO9075.encode("_x0020_Documents"))); + assertEquals("@_x0020_Documents", ISO9075.decode(ISO9075.encode("@_x0020_Documents"))); + assertEquals("Andy's Bits & Bobs \uabcd", ISO9075.decode(ISO9075.encode("Andy's Bits & Bobs \uabcd"))); + assertEquals("Andy's Bits & Bobs \uabcd\\", ISO9075.decode(ISO9075.encode("Andy's Bits & Bobs \uabcd\\"))); + assertEquals( + " `\u00ac\u00a6!\"\u00a3$%^&*()-_=+\t\n\\\u0000[]{};'#:@~,./<>?\\|", + ISO9075.decode(ISO9075.encode(" `\u00ac\u00a6!\"\u00a3$%^&*()-_=+\t\n\\\u0000[]{};'#:@~,./<>?\\|"))); + assertEquals("\u0123\u4567\u8900\uabcd\uefff_xT65A_", ISO9075.decode(ISO9075.encode("\u0123\u4567\u8900\uabcd\uefff_xT65A_"))); + } + + public void testRoundTrip2() + { + assertEquals("MyDocuments", ISO9075.encode(ISO9075.decode("MyDocuments"))); + assertEquals("My_Documents", ISO9075.encode(ISO9075.decode("My_Documents"))); + assertEquals("My_x0020_Documents", ISO9075.encode(ISO9075.decode("My_x0020_Documents"))); + assertEquals("My_x0020Documents", ISO9075.encode(ISO9075.decode("My_x0020Documents"))); + assertEquals("My_x005f_x0020_Documents", ISO9075.encode(ISO9075.decode("My_x005f_x0020_Documents"))); + assertEquals("_x005f_x0020_Documents", ISO9075.encode(ISO9075.decode("_x005f_x0020_Documents"))); + assertEquals("_x0040__x005f_x0020_Documents", ISO9075.encode(ISO9075.decode("_x0040__x005f_x0020_Documents"))); + assertEquals("Andy_x0027_s_x0020_Bits_x0020__x0026__x0020_Bobs_x0020__xabcd_", ISO9075.encode(ISO9075 + .decode("Andy_x0027_s_x0020_Bits_x0020__x0026__x0020_Bobs_x0020__xabcd_"))); + assertEquals("Andy_x0027_s_x0020_Bits_x0020__x0026__x0020_Bobs_x0020__xabcd__x005c_", ISO9075.encode(ISO9075 + .decode("Andy_x0027_s_x0020_Bits_x0020__x0026__x0020_Bobs_x0020__xabcd__x005c_"))); + assertEquals( + "_x0020__x0060__x00ac__x00a6__x0021__x0022__x00a3__x0024__x0025__x005e__x0026__x002a__x0028__x0029_-__x003d__x002b__x0009__x000a__x005c__x0000__x005b__x005d__x007b__x007d__x003b__x0027__x0023__x003a__x0040__x007e__x002c_._x002f__x003c__x003e__x003f__x005c__x007c_", + ISO9075.encode(ISO9075 + .decode("_x0020__x0060__x00ac__x00a6__x0021__x0022__x00a3__x0024__x0025__x005e__x0026__x002a__x0028__x0029_-__x003d__x002b__x0009__x000a__x005c__x0000__x005b__x005d__x007b__x007d__x003b__x0027__x0023__x003a__x0040__x007e__x002c_._x002f__x003c__x003e__x003f__x005c__x007c_"))); + assertEquals("\u0123_x4567_\u8900_xabcd__xefff__xT65A_", ISO9075.encode(ISO9075 + .decode("\u0123_x4567_\u8900_xabcd__xefff__xT65A_"))); } }