From cfb373ae366f31714c2ac8c9be03d0bf225e0648 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Tue, 19 Dec 2006 14:24:45 +0000 Subject: [PATCH] Merge 1.4 to HEAD svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4340 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4350 . svn resolved root\projects\3rd-party\.classpath svn resolved root\projects\repository\source\java\org\alfresco\repo\workflow\WorkflowInterpreter.java svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4379 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4380 . svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4420 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4421 . svn resolved root\projects\3rd-party\.classpath git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4655 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/bootstrap/categories.xml | 4 +- config/alfresco/content-services-context.xml | 8 + .../messages/patch-service.properties | 45 ++-- .../messages/system-messages.properties | 6 +- .../mimetype/openoffice-document-formats.xml | 4 +- config/alfresco/model/contentModel.xml | 2 +- .../alfresco/patch/patch-services-context.xml | 15 ++ config/alfresco/version.properties | 2 +- .../repo/admin/ConfigurationChecker.java | 12 +- .../patch/impl/InvalidNameEndingPatch.java | 205 ++++++++++++++++++ .../patch/impl/UniqueChildNamePatch.java | 18 +- .../metadata/OpenOfficeMetadataExtracter.java | 36 ++- .../OpenOfficeContentTransformer.java | 28 ++- .../domain/hibernate/HibernateNodeTest.java | 2 +- .../repo/node/db/DbNodeServiceImpl.java | 2 +- .../repo/workflow/WorkflowInterpreter.java | 48 +++- .../util/OpenOfficeConnectionTester.java | 106 +++++++++ 17 files changed, 473 insertions(+), 70 deletions(-) create mode 100644 source/java/org/alfresco/repo/admin/patch/impl/InvalidNameEndingPatch.java create mode 100644 source/java/org/alfresco/util/OpenOfficeConnectionTester.java diff --git a/config/alfresco/bootstrap/categories.xml b/config/alfresco/bootstrap/categories.xml index 5e33800a75..760fe4f589 100644 --- a/config/alfresco/bootstrap/categories.xml +++ b/config/alfresco/bootstrap/categories.xml @@ -882,7 +882,7 @@ Saint Lucia - Saint Vincent and Grenadines. + Saint Vincent and Grenadines Trinidad and Tobago @@ -891,7 +891,7 @@ Turks and Caicos Islands - United States Virgin Islands. + United States Virgin Islands diff --git a/config/alfresco/content-services-context.xml b/config/alfresco/content-services-context.xml index c62faa4fc4..81485cd296 100644 --- a/config/alfresco/content-services-context.xml +++ b/config/alfresco/content-services-context.xml @@ -100,6 +100,14 @@ + + + + + + false + + diff --git a/config/alfresco/messages/patch-service.properties b/config/alfresco/messages/patch-service.properties index aad05f496d..a51c36136d 100644 --- a/config/alfresco/messages/patch-service.properties +++ b/config/alfresco/messages/patch-service.properties @@ -19,16 +19,16 @@ patch.general.property_not_set=Patch property ''{0}'' has not been set on this p patch.marker.description=Marker patch to record installations and upgrades patch.marker.result=Marker patch applied -patch.savedSearchesFolder.description=Ensures the existence of the 'Saved Searches' folder. +patch.savedSearchesFolder.description=Ensures the existence of the ''Saved Searches'' folder. patch.savedSearchesFolder.result.exists=The saved searches folder already exists: {0} patch.savedSearchesFolder.result.created=The saved searches folder was successfully created: {0} -patch.savedSearchesPermission.description=Sets required permissions on 'Saved Searches' folder. +patch.savedSearchesPermission.description=Sets required permissions on ''Saved Searches'' folder. patch.savedSearchesPermission.result.applied=Granted CONTRIBUTOR role to EVERYONE on ''Saved Searches'' folder: {0}. -patch.savedSearchesPermission.err.not_found='Saved Searches' folder could not be found. +patch.savedSearchesPermission.err.not_found=''Saved Searches'' folder could not be found. -patch.updatePermissionData.description=Update permissions from 'folder' to 'cmobject' [JIRA: AR-344]. -patch.updatePermissionData.result=Changed {0} 'folder' access control entries to 'cmobject'. +patch.updatePermissionData.description=Update permissions from ''folder'' to ''cmobject'' [JIRA: AR-344]. +patch.updatePermissionData.result=Changed {0} ''folder'' access control entries to ''cmobject''. patch.authoritiesFolder.description=Ensures the existence of the user authorities folder [JIRA: AR-497]. @@ -38,26 +38,26 @@ patch.guestUser.result=Added guest user and fixed permissions. patch.fixNodeSerializableValues.description=Ensure that property values are not stored as Serializable if at all possible patch.fixNodeSerializableValues.result=Fixed {0} node property serialized values -patch.updateGuestPermission.description=Rename guest permission from 'Guest' to 'Consumer' -patch.updateGuestPermission.result=Changed {0} 'Guest' access control entries to 'Consumer'. +patch.updateGuestPermission.description=Rename guest permission from 'Guest' to ''Consumer'' +patch.updateGuestPermission.result=Changed {0} ''Guest'' access control entries to ''Consumer''. -patch.categoryRootPermission.description=Sets required permissions on 'Category Root' folder. +patch.categoryRootPermission.description=Sets required permissions on ''Category Root'' folder. patch.categoryRootPermission.result=Granted CONSUMER role to GUEST on ''Category Root'' folder: {0}. -patch.categoryRootPermission.err.not_found='Category Root' folder ({0}) could not be found. +patch.categoryRootPermission.err.not_found=''Category Root'' folder ({0}) could not be found. -patch.guestPersonPermission.description=Change Guest Person permission from 'Consumer' to 'Read' -patch.guestPersonPermission.result=Updated Guest Person permission from 'Consumer' to 'Read' +patch.guestPersonPermission.description=Change Guest Person permission from ''Consumer'' to ''Read'' +patch.guestPersonPermission.result=Updated Guest Person permission from ''Consumer'' to ''Read'' -patch.spacesRootPermission.description=Change Spaces store root permission from 'Consumer' to 'Read' -patch.spacesRootPermission.result=Updated Spaces store root permission from 'Consumer' to 'Read' +patch.spacesRootPermission.description=Change Spaces store root permission from ''Consumer'' to ''Read'' +patch.spacesRootPermission.result=Updated Spaces store root permission from ''Consumer'' to ''Read'' -patch.contentPermission.description=Update permission entries from 'cm:content' to 'sys:base'. -patch.contentPermission.result=Changed {0} 'cm:content' access control entries to 'sys:base'. +patch.contentPermission.description=Update permission entries from 'cm:content' to ''sys:base''. +patch.contentPermission.result=Changed {0} ''cm:content'' access control entries to ''sys:base''. patch.forumsIcons.description=Updates forums icon references patch.forumsIcons.result=Updated {0} icon references -patch.emailTemplatesFolder.description=Ensures the existence of the 'Email Templates' folder. +patch.emailTemplatesFolder.description=Ensures the existence of the ''Email Templates'' folder. patch.emailTemplatesFolder.result.exists=The email templates folder already exists: {0} patch.emailTemplatesFolder.result.created=The email templates folder was successfully created: {0} @@ -67,7 +67,7 @@ patch.emailTemplatesContent.result=Imported the Email Templates into the default patch.descriptorUpdate.description=Update Repository descriptor patch.descriptorUpdate.result=Repository descriptor updated -patch.scriptsFolder.description=Ensures the existence of the 'Scripts' folder. +patch.scriptsFolder.description=Ensures the existence of the ''Scripts'' folder. patch.scriptsFolder.result.exists=The scripts folder already exists: {0} patch.scriptsFolder.result.created=The scripts folder was successfully created: {0} @@ -82,15 +82,15 @@ patch.actionRuleDecouplingPatch.result=Updated {0} rules. patch.systemWorkflowFolder.description=Ensures the existence of the system workflow container. patch.systemWorkflowFolder.result.created=Created system workflow container {0}. -patch.rssTemplatesFolder.description=Ensures the existence of the 'RSS Templates' folder. +patch.rssTemplatesFolder.description=Ensures the existence of the ''RSS Templates'' folder. patch.rssTemplatesFolder.result.exists=The RSS Templates folder already exists: {0} patch.rssTemplatesFolder.result.created=The RSS Templates folder was successfully created: {0} patch.uifacetsAspectRemovalPatch.description=Removes the incorrectly applied uifacets aspect from presentation template files. patch.uifacetsAspectRemovalPatch.updated=Successfully removed the uifacets aspect from {0} presentation template files. -patch.guestPersonPermission2.description=Change Guest Person permission to visible by all users as 'Consumer'. -patch.guestPersonPermission2.result=Updated Guest Person permission to visible by all users as 'Consumer'. +patch.guestPersonPermission2.description=Change Guest Person permission to visible by all users as ''Consumer''. +patch.guestPersonPermission2.result=Updated Guest Person permission to visible by all users as ''Consumer''. patch.schemaUpgradeScript.description=Ensures that the database upgrade script has been run. patch.schemaUpgradeScript.err.not_executed=The schema upgrade script, ''{0}'', has not been run against this database. @@ -99,3 +99,8 @@ patch.uniqueChildName.description=Checks and renames duplicate children. patch.uniqueChildName.copyOf=({0}-{1}) patch.uniqueChildName.result=Checked {0} associations and fixed {1} duplicates. See file {2} for details. patch.uniqueChildName.err.unable_to_fix=Auto-fixing of duplicate names failed. See file {0} for details. + +patch.invalidNameEnding.description=Fixes names ending with a space or full stop. +patch.invalidNameEnding.result=Fixed {0} names ending with a space or full stop. See file {1} for details. +patch.invalidNameEnding.err.unable_to_fix=Auto-fixing of names ending with a space or full stop failed. See file {0} for details. +patch.invalidNameEnding.rewritten=Name ''{0}'' rewritten to ''{1}'' diff --git a/config/alfresco/messages/system-messages.properties b/config/alfresco/messages/system-messages.properties index f1a1b6e4d9..f281f4e37e 100644 --- a/config/alfresco/messages/system-messages.properties +++ b/config/alfresco/messages/system-messages.properties @@ -12,4 +12,8 @@ system.config_check.err.missing_index=CONTENT INTEGRITY ERROR: Indexes not found system.config_check.err.missing_content=CONTENT INTEGRITY ERROR: Content not found for {0} stores. system.config_check.err.fix_dir_root=Ensure that the ''dir.root'' property is pointing to the correct data location. system.config_check.msg.howto_index_recover=You may set 'index.recovery.mode=FULL' if you need to rebuild the indexes. -system.config_check.warn.starting_with_errors=Alfresco is starting with errors. \ No newline at end of file +system.config_check.warn.starting_with_errors=Alfresco is starting with errors. + +# OpenOffice +system.openoffice.info.connection_verified=The connection to OpenOffice has been established. +system.openoffice.err.connection_failed=A connection to OpenOffice could not be established. \ No newline at end of file diff --git a/config/alfresco/mimetype/openoffice-document-formats.xml b/config/alfresco/mimetype/openoffice-document-formats.xml index 9579d1ba0d..34fcb50e6d 100644 --- a/config/alfresco/mimetype/openoffice-document-formats.xml +++ b/config/alfresco/mimetype/openoffice-document-formats.xml @@ -10,7 +10,6 @@ Presentationimpress_pdf_Export Spreadsheetcalc_pdf_Export Textwriter_pdf_Export - Htmlwriter_web_pdf_Export @@ -28,7 +27,7 @@ - 2. output quality does not seem to be very good in many cases --> Html - Html + Text text/html html @@ -46,7 +45,6 @@ odt Textwriter8 - Htmlwriterweb8_writer diff --git a/config/alfresco/model/contentModel.xml b/config/alfresco/model/contentModel.xml index 8070df71d9..804b6645cd 100644 --- a/config/alfresco/model/contentModel.xml +++ b/config/alfresco/model/contentModel.xml @@ -16,7 +16,7 @@ - \<\?\/\:\|\xA3\xAC\%\&\+\;]+.*]]> + \<\?\/\:\|\xA3\xAC\%\&\+\;]+.*)|(.*[\.]?.*[\.]+$)|(.*[ ]+$)]]> false diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml index dda2c969e9..f289ed598a 100644 --- a/config/alfresco/patch/patch-services-context.xml +++ b/config/alfresco/patch/patch-services-context.xml @@ -469,6 +469,7 @@ + @@ -488,5 +489,19 @@ + + patch.InvalidNameEnding + patch.invalidNameEnding.description + 0 + 21 + 22 + + + + + + + + diff --git a/config/alfresco/version.properties b/config/alfresco/version.properties index f405cf012a..2ca1eb46fa 100644 --- a/config/alfresco/version.properties +++ b/config/alfresco/version.properties @@ -19,4 +19,4 @@ version.build=@build-number@ # Schema number -version.schema=21 +version.schema=22 diff --git a/source/java/org/alfresco/repo/admin/ConfigurationChecker.java b/source/java/org/alfresco/repo/admin/ConfigurationChecker.java index 3e3a3c77fd..25a455ac08 100644 --- a/source/java/org/alfresco/repo/admin/ConfigurationChecker.java +++ b/source/java/org/alfresco/repo/admin/ConfigurationChecker.java @@ -33,6 +33,7 @@ import org.alfresco.service.cmr.dictionary.PropertyDefinition; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.InvalidStoreRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.StoreRef; @@ -213,7 +214,16 @@ public class ConfigurationChecker extends AbstractLifecycleBean List missingContentStoreRefs = new ArrayList(0); for (StoreRef storeRef : storeRefs) { - NodeRef rootNodeRef = nodeService.getRootNode(storeRef); + NodeRef rootNodeRef = null; + try + { + rootNodeRef = nodeService.getRootNode(storeRef); + } + catch (InvalidStoreRefException e) + { + // the store is invalid and will therefore not have a root node entry + continue; + } if (indexRecoveryMode != RecoveryMode.FULL) { if (logger.isDebugEnabled()) diff --git a/source/java/org/alfresco/repo/admin/patch/impl/InvalidNameEndingPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/InvalidNameEndingPatch.java new file mode 100644 index 0000000000..05205f7487 --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/InvalidNameEndingPatch.java @@ -0,0 +1,205 @@ +/* + * 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.admin.patch.impl; + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.Date; +import java.util.List; + +import org.alfresco.i18n.I18NUtil; +import org.alfresco.model.ContentModel; +import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.domain.hibernate.NodeImpl; +import org.alfresco.repo.node.db.NodeDaoService; +import org.alfresco.service.cmr.admin.PatchException; +import org.alfresco.service.cmr.repository.DuplicateChildNodeNameException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.springframework.orm.hibernate3.HibernateCallback; +import org.springframework.orm.hibernate3.support.HibernateDaoSupport; + +/** + * Checks that all names do not end with ' ' or '.' + * + * @author David Caruana + */ +public class InvalidNameEndingPatch extends AbstractPatch +{ + private static final String MSG_SUCCESS = "patch.invalidNameEnding.result"; + private static final String MSG_REWRITTEN = "patch.invalidNameEnding.rewritten"; + private static final String ERR_UNABLE_TO_FIX = "patch.invalidNameEnding.err.unable_to_fix"; + + private SessionFactory sessionFactory; + private NodeDaoService nodeDaoService; + + public InvalidNameEndingPatch() + { + } + + public void setSessionFactory(SessionFactory sessionFactory) + { + this.sessionFactory = sessionFactory; + } + + /** + * @param nodeDaoService The service that generates the CRC values + */ + public void setNodeDaoService(NodeDaoService nodeDaoService) + { + this.nodeDaoService = nodeDaoService; + } + + @Override + protected void checkProperties() + { + super.checkProperties(); + checkPropertyNotNull(sessionFactory, "sessionFactory"); + checkPropertyNotNull(nodeDaoService, "nodeDaoService"); + } + + @Override + protected String applyInternal() throws Exception + { + // initialise the helper + HibernateHelper helper = new HibernateHelper(); + helper.setSessionFactory(sessionFactory); + + try + { + String msg = helper.fixNames(); + // done + return msg; + } + finally + { + helper.closeWriter(); + } + } + + private class HibernateHelper extends HibernateDaoSupport + { + private File logFile; + private FileChannel channel; + + private HibernateHelper() throws IOException + { + logFile = new File("./InvalidNameEndingPatch.log"); + // open the file for appending + RandomAccessFile outputFile = new RandomAccessFile(logFile, "rw"); + channel = outputFile.getChannel(); + // move to the end of the file + channel.position(channel.size()); + // add a newline and it's ready + writeLine("").writeLine(""); + writeLine("InvalidNameEndingPatch executing on " + new Date()); + } + + private HibernateHelper write(Object obj) throws IOException + { + channel.write(ByteBuffer.wrap(obj.toString().getBytes())); + return this; + } + private HibernateHelper writeLine(Object obj) throws IOException + { + write(obj); + write("\n"); + return this; + } + private void closeWriter() + { + try { channel.close(); } catch (Throwable e) {} + } + + public String fixNames() throws Exception + { + // get the association types to check + @SuppressWarnings("unused") + List nodes = getInvalidNames(); + + int updated = 0; + for (NodeImpl node : nodes) + { + NodeRef nodeRef = node.getNodeRef(); + String name = (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); + if (name != null && (name.endsWith(".") || name.endsWith(" "))) + { + int i = (name.length() == 0) ? 0 : name.length() - 1; + while (i >= 0 && (name.charAt(i) == '.' || name.charAt(i) == ' ')) + { + i--; + } + + String updatedName = name.substring(0, i); + int idx = 0; + boolean applied = false; + while (!applied) + { + try + { + nodeService.setProperty(nodeRef, ContentModel.PROP_NAME, updatedName); + applied = true; + } + catch(DuplicateChildNodeNameException e) + { + idx++; + if (idx > 10) + { + writeLine(I18NUtil.getMessage(ERR_UNABLE_TO_FIX, name ,updatedName)); + throw new PatchException(ERR_UNABLE_TO_FIX, logFile); + } + updatedName += "_" + idx; + } + } + writeLine(I18NUtil.getMessage(MSG_REWRITTEN, name ,updatedName)); + updated++; + getSession().flush(); + getSession().clear(); + } + } + + String msg = I18NUtil.getMessage(MSG_SUCCESS, updated, logFile); + return msg; + } + + @SuppressWarnings("unchecked") + private List getInvalidNames() + { + HibernateCallback callback = new HibernateCallback() + { + public Object doInHibernate(Session session) + { + Query query = session + .createQuery( + "select node from org.alfresco.repo.domain.hibernate.NodeImpl as node " + + "join node.properties prop where " + + " prop.stringValue like '%.' or " + + " prop.stringValue like '% ' "); + return query.list(); + } + }; + List results = (List) getHibernateTemplate().execute(callback); + return results; + } + + } +} diff --git a/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java b/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java index 4fde56eac5..aa0f4a3412 100644 --- a/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java +++ b/source/java/org/alfresco/repo/admin/patch/impl/UniqueChildNamePatch.java @@ -104,10 +104,16 @@ public class UniqueChildNamePatch extends AbstractPatch HibernateHelper helper = new HibernateHelper(); helper.setSessionFactory(sessionFactory); - String msg = helper.assignCrc(); - - // done - return msg; + try + { + String msg = helper.assignCrc(); + // done + return msg; + } + finally + { + helper.closeWriter(); + } } private class HibernateHelper extends HibernateDaoSupport @@ -139,6 +145,10 @@ public class UniqueChildNamePatch extends AbstractPatch write("\n"); return this; } + private void closeWriter() + { + try { channel.close(); } catch (Throwable e) {} + } public String assignCrc() throws Exception { diff --git a/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java b/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java index 3511b627f8..78ab90cde4 100644 --- a/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java +++ b/source/java/org/alfresco/repo/content/metadata/OpenOfficeMetadataExtracter.java @@ -57,7 +57,6 @@ public class OpenOfficeMetadataExtracter extends AbstractMetadataExtracter }; private OpenOfficeConnection connection; - private boolean isConnected; public OpenOfficeMetadataExtracter() { @@ -69,6 +68,25 @@ public class OpenOfficeMetadataExtracter extends AbstractMetadataExtracter this.connection = connection; } + private synchronized void connect() + { + if (isConnected()) + { + // just leave it + } + else + { + try + { + connection.connect(); + } + catch (ConnectException e) + { + logger.warn(e.getMessage()); + } + } + } + /** * Initialises the bean by establishing an UNO connection */ @@ -76,18 +94,14 @@ public class OpenOfficeMetadataExtracter extends AbstractMetadataExtracter { PropertyCheck.mandatory("OpenOfficeMetadataExtracter", "connection", connection); - // attempt to make an connection - try + // attempt a connection + connect(); + if (isConnected()) { - connection.connect(); - isConnected = true; - // register + // Only register if the connection is available initially. Reconnections are only supported + // if the server is able to connection initially. super.register(); } - catch (ConnectException e) - { - isConnected = false; - } } /** @@ -96,7 +110,7 @@ public class OpenOfficeMetadataExtracter extends AbstractMetadataExtracter */ public boolean isConnected() { - return isConnected; + return connection.isConnected(); } public void extractInternal(ContentReader reader, final Map destination) throws Throwable diff --git a/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java b/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java index 007144d77c..67d8702dfc 100644 --- a/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java +++ b/source/java/org/alfresco/repo/content/transform/OpenOfficeContentTransformer.java @@ -53,14 +53,12 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer private static Log logger = LogFactory.getLog(OpenOfficeContentTransformer.class); private OpenOfficeConnection connection; - private boolean connected; private OpenOfficeDocumentConverter converter; private String documentFormatsConfiguration; private DocumentFormatRegistry formatRegistry; public OpenOfficeContentTransformer() { - this.connected = false; } public void setConnection(OpenOfficeConnection connection) @@ -80,20 +78,25 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer public boolean isConnected() { - return connected; + return connection.isConnected(); } private synchronized void connect() { - try + if (isConnected()) { - connection.connect(); - connected = true; + // just leave it } - catch (ConnectException e) + else { - logger.warn(e.getMessage()); - connected = false; + try + { + connection.connect(); + } + catch (ConnectException e) + { + logger.warn(e.getMessage()); + } } } @@ -128,9 +131,10 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer formatRegistry = new XmlDocumentFormatRegistry(); } - if (connected) + if (isConnected()) { - // register + // If the server starts with OO running, then it will attempt reconnections. Otherwise it will + // just be wasting time trying to see if a connection is available all the time. super.register(); } } @@ -140,7 +144,7 @@ public class OpenOfficeContentTransformer extends AbstractContentTransformer */ public double getReliability(String sourceMimetype, String targetMimetype) { - if (!connected) + if (!isConnected()) { return 0.0; } diff --git a/source/java/org/alfresco/repo/domain/hibernate/HibernateNodeTest.java b/source/java/org/alfresco/repo/domain/hibernate/HibernateNodeTest.java index 2eb1b7d4e7..e773deb485 100644 --- a/source/java/org/alfresco/repo/domain/hibernate/HibernateNodeTest.java +++ b/source/java/org/alfresco/repo/domain/hibernate/HibernateNodeTest.java @@ -70,7 +70,7 @@ public class HibernateNodeTest extends BaseSpringTest { store = new StoreImpl(); StoreKey storeKey = new StoreKey(StoreRef.PROTOCOL_WORKSPACE, - "TestWorkspace@" + System.currentTimeMillis() + " - " + System.nanoTime()); + "TestWorkspace@" + getName() + " - " + System.currentTimeMillis()); store.setKey(storeKey); // persist so that it is present in the hibernate cache getSession().save(store); diff --git a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java index 65d0f59fd8..f197c67832 100644 --- a/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/DbNodeServiceImpl.java @@ -220,7 +220,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl Node node = store.getRootNode(); if (node == null) { - throw new InvalidStoreRefException("Store does not have a root node", storeRef); + throw new InvalidStoreRefException("Store does not have a root node: " + storeRef, storeRef); } NodeRef nodeRef = node.getNodeRef(); // done diff --git a/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java b/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java index 94bad519cb..d2056ee152 100644 --- a/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java +++ b/source/java/org/alfresco/repo/workflow/WorkflowInterpreter.java @@ -37,6 +37,7 @@ import org.alfresco.service.cmr.avm.AVMNodeDescriptor; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.avmsync.AVMDifference; import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.ContentWriter; @@ -86,6 +87,7 @@ public class WorkflowInterpreter private WorkflowDefinition currentWorkflowDef = null; private WorkflowPath currentPath = null; private String currentDeploy = null; + private String username = "admin"; /** * Last command issued @@ -105,7 +107,6 @@ public class WorkflowInterpreter { ApplicationContext context = ApplicationContextHelper.getApplicationContext(); WorkflowInterpreter console = (WorkflowInterpreter)context.getBean("workflowInterpreter"); - AuthenticationUtil.setSystemUserAsCurrentUser(); console.rep(); System.exit(0); } @@ -179,16 +180,20 @@ public class WorkflowInterpreter */ public void rep() { + // accept commands while (true) { System.out.print("ok> "); try { - String line = fIn.readLine(); + // get command + final String line = fIn.readLine(); if (line.equals("exit") || line.equals("quit")) { return; } + + // execute command in context of currently selected user long startms = System.currentTimeMillis(); System.out.print(interpretCommand(line)); System.out.println("" + (System.currentTimeMillis() - startms) + "ms"); @@ -204,12 +209,31 @@ public class WorkflowInterpreter /** * Interpret a single command using the BufferedReader passed in for any data needed. * + * @param line The unparsed command + * @return The textual output of the command. + */ + public String interpretCommand(final String line) + throws IOException + { + // execute command in context of currently selected user + return AuthenticationUtil.runAs(new RunAsWork() + { + public String doWork() throws Exception + { + return executeCommand(line); + } + }, username); + } + + /** + * Execute a single command using the BufferedReader passed in for any data needed. + * * TODO: Use decent parser! * * @param line The unparsed command * @return The textual output of the command. */ - public String interpretCommand(String line) + private String executeCommand(String line) throws IOException { String[] command = line.split(" "); @@ -229,7 +253,7 @@ public class WorkflowInterpreter { return "No command entered yet."; } - return "repeating command " + lastCommand + "\n\n" + interpretCommand(lastCommand); + return "repeating command " + lastCommand + "\n\n" + executeCommand(lastCommand); } // remember last command @@ -500,7 +524,7 @@ public class WorkflowInterpreter } out.println("deployed definition id: " + def.id + " , name: " + def.name + " , title: " + def.title + " , version: " + def.version); currentDeploy = command[1]; - out.print(interpretCommand("use definition " + def.id)); + out.print(executeCommand("use definition " + def.id)); } else if (command[0].equals("redeploy")) @@ -509,7 +533,7 @@ public class WorkflowInterpreter { return "nothing to redeploy\n"; } - out.print(interpretCommand("deploy " + currentDeploy)); + out.print(executeCommand("deploy " + currentDeploy)); } else if (command[0].equals("undeploy")) @@ -527,7 +551,7 @@ public class WorkflowInterpreter workflowService.undeployDefinition(command[2]); currentWorkflowDef = null; currentPath = null; - out.print(interpretCommand("show definitions")); + out.print(executeCommand("show definitions")); } } @@ -554,7 +578,7 @@ public class WorkflowInterpreter } currentWorkflowDef = def; currentPath = null; - out.print(interpretCommand("use")); + out.print(executeCommand("use")); } else if (command[1].equals("workflow")) @@ -566,7 +590,7 @@ public class WorkflowInterpreter WorkflowInstance instance = workflowService.getWorkflowById(command[2]); currentWorkflowDef = instance.definition; currentPath = workflowService.getWorkflowPaths(instance.id).get(0); - out.print(interpretCommand("use")); + out.print(executeCommand("use")); } else { @@ -579,9 +603,9 @@ public class WorkflowInterpreter { if (command.length == 2) { - AuthenticationUtil.setCurrentUser(command[1]); + username = command[1]; } - out.println("using user " + AuthenticationUtil.getCurrentUserName()); + out.println("using user " + username); } else if (command[0].equals("start")) @@ -942,7 +966,7 @@ public class WorkflowInterpreter */ public String getCurrentUserName() { - return AuthenticationUtil.getCurrentUserName(); + return username; } } \ No newline at end of file diff --git a/source/java/org/alfresco/util/OpenOfficeConnectionTester.java b/source/java/org/alfresco/util/OpenOfficeConnectionTester.java new file mode 100644 index 0000000000..d566b4ae27 --- /dev/null +++ b/source/java/org/alfresco/util/OpenOfficeConnectionTester.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2006 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.util; + +import java.net.ConnectException; + +import net.sf.jooreports.openoffice.connection.OpenOfficeConnection; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.i18n.I18NUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Simple class that checks for the presence of a valid OpenOffice + * connection, as provided by the + * net.sf.jooreports.openoffice.connection.OpenOfficeConnection implementations. + * + * @author Derek Hulley + */ +public class OpenOfficeConnectionTester +{ + private static final String INFO_CONNECTION_VERIFIED = "system.openoffice.info.connection_verified"; + private static final String ERR_CONNECTION_FAILED = "system.openoffice.err.connection_failed"; + + private static Log logger = LogFactory.getLog(OpenOfficeConnectionTester.class); + + private OpenOfficeConnection connection; + private boolean strict; + + public OpenOfficeConnectionTester() + { + this.strict = false; + } + + /** + * @param connection the OpenOffice connection. + */ + public void setConnection(OpenOfficeConnection connection) + { + this.connection = connection; + } + + /** + * @param strict set to true to generate a failure if the connection is not connected + * during the {@link #checkConnection() connection check}, or false to just issue + * a warning. The default is false. + */ + public void setStrict(boolean strict) + { + this.strict = strict; + } + + /** + * Perform the actual connection check. If this component is {@link #setStrict(boolean) strict}, + * then a disconnected {@link #setConnection(OpenOfficeConnection) connection} will result in a + * runtime exception being generated. + */ + public synchronized void checkConnection() + { + PropertyCheck.mandatory(this, "connection", connection); + String connectedMessage = I18NUtil.getMessage(INFO_CONNECTION_VERIFIED); + if (connection.isConnected()) + { + // the connection is fine + logger.info(connectedMessage); + return; + } + // attempt to make the connection + try + { + connection.connect(); + // that worked + logger.info(connectedMessage); + return; + } + catch (ConnectException e) + { + // no luck + } + // now we have to either fail or report the connection + String msg = I18NUtil.getMessage(ERR_CONNECTION_FAILED); + if (strict) + { + throw new AlfrescoRuntimeException(msg); + } + else + { + logger.warn(msg); + } + } +}