diff --git a/config/alfresco/extension/ldap-authentication-context.xml.sample b/config/alfresco/extension/ldap-authentication-context.xml.sample index efab14b064..d024f42463 100644 --- a/config/alfresco/extension/ldap-authentication-context.xml.sample +++ b/config/alfresco/extension/ldap-authentication-context.xml.sample @@ -20,6 +20,9 @@ true + + true + diff --git a/config/alfresco/messages/dictionary-messages.properties b/config/alfresco/messages/dictionary-messages.properties index 7bbe0556bb..27e8f1e966 100644 --- a/config/alfresco/messages/dictionary-messages.properties +++ b/config/alfresco/messages/dictionary-messages.properties @@ -25,6 +25,7 @@ d_dictionary.property.err.cannot_relax_mandatory_enforcement=Cannot relax mandat d_dictionary.constraint.regex.no_match=Value ''{0}'' does not match regular expression: {1} d_dictionary.constraint.regex.match=Value ''{0}'' matches regular expression: {1} +d_dictionary.constraint.regex.error.cm\:filename=Value ''{0}'' is not valid as a file name. This property must be a valid file name. d_dictionary.constraint.numeric_range.invalid_min_value=Invalid 'minValue' property: {0} d_dictionary.constraint.numeric_range.invalid_max_value=Invalid 'maxValue' property: {0} diff --git a/source/java/org/alfresco/repo/avm/AVMNodeService.java b/source/java/org/alfresco/repo/avm/AVMNodeService.java index 04c1ce9456..3012f46e54 100644 --- a/source/java/org/alfresco/repo/avm/AVMNodeService.java +++ b/source/java/org/alfresco/repo/avm/AVMNodeService.java @@ -308,7 +308,7 @@ public class AVMNodeService extends AbstractNodeServiceImpl implements NodeServi { // TODO Need to find out if this is important and if so // need to capture Transaction IDs. - return new NodeRef.Status("Unknown", !exists(nodeRef)); + return new NodeRef.Status("Unknown", null, !exists(nodeRef)); } /** diff --git a/source/java/org/alfresco/repo/dictionary/M2ConstraintDefinition.java b/source/java/org/alfresco/repo/dictionary/M2ConstraintDefinition.java index dc016d34d6..176cc3f46e 100644 --- a/source/java/org/alfresco/repo/dictionary/M2ConstraintDefinition.java +++ b/source/java/org/alfresco/repo/dictionary/M2ConstraintDefinition.java @@ -226,6 +226,24 @@ import org.springframework.beans.PropertyAccessException; throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValue.getName(), shortName); } } + + // Pass in the name as a special property, if it is available + if (beanWrapper.isWritableProperty("_shortName")) + { + try + { + beanWrapper.setPropertyValue("_shortName", shortName); + } + catch (PropertyAccessException e) + { + throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, shortName, shortName); + } + catch (InvalidPropertyException e) + { + throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, shortName, shortName); + } + + } } // now initialize constraint.initialize(); diff --git a/source/java/org/alfresco/repo/dictionary/constraint/AbstractConstraint.java b/source/java/org/alfresco/repo/dictionary/constraint/AbstractConstraint.java index b7de444c4e..88718f5db7 100644 --- a/source/java/org/alfresco/repo/dictionary/constraint/AbstractConstraint.java +++ b/source/java/org/alfresco/repo/dictionary/constraint/AbstractConstraint.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,7 +18,7 @@ * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's - * FLOSS exception. You should have recieved a copy of the text describing + * FLOSS exception. You should have received a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ @@ -40,6 +40,31 @@ public abstract class AbstractConstraint implements Constraint { public static final String ERR_PROP_NOT_SET = "d_dictionary.constraint.err.property_not_set"; public static final String ERR_EVALUATE_EXCEPTION = "d_dictionary.constraint.err.evaluate_exception"; + + + /** The constraint name. May be useful in error messages */ + private String shortName; + + /** + * Sets the constraint name. Automatically called after construction. Please excuse the strange method name as we + * want the property name to begin with an underscore to avoid property name clashes. + * + * @param shortName + */ + public void set_shortName(String shortName) + { + this.shortName = shortName; + } + + /** + * Gets the constraint name. May be useful in error messages. + * + * @return the constraint name. + */ + public String getShortName() + { + return this.shortName; + } /* * @see org.alfresco.service.cmr.dictionary.Constraint#getType() diff --git a/source/java/org/alfresco/repo/dictionary/constraint/RegexConstraint.java b/source/java/org/alfresco/repo/dictionary/constraint/RegexConstraint.java index 177a4e46da..11299e1e01 100644 --- a/source/java/org/alfresco/repo/dictionary/constraint/RegexConstraint.java +++ b/source/java/org/alfresco/repo/dictionary/constraint/RegexConstraint.java @@ -29,6 +29,7 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.alfresco.i18n.I18NUtil; import org.alfresco.service.cmr.dictionary.ConstraintException; import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; @@ -51,6 +52,7 @@ public class RegexConstraint extends AbstractConstraint { public static final String CONSTRAINT_REGEX_NO_MATCH = "d_dictionary.constraint.regex.no_match"; public static final String CONSTRAINT_REGEX_MATCH = "d_dictionary.constraint.regex.match"; + public static final String CONSTRAINT_REGEX_MSG_PREFIX = "d_dictionary.constraint.regex.error."; private String expression; private Pattern patternMatcher; @@ -127,7 +129,14 @@ public class RegexConstraint extends AbstractConstraint boolean matches = matcher.matches(); if (matches != requiresMatch) { - if (requiresMatch) + // Look for a message corresponding to this constraint name + String messageId = CONSTRAINT_REGEX_MSG_PREFIX + getShortName(); + if (I18NUtil.getMessage(messageId, value) != null) + { + throw new ConstraintException(messageId, value); + } + // Otherwise, fall back to a generic (but unfriendly) message + else if (requiresMatch) { throw new ConstraintException(RegexConstraint.CONSTRAINT_REGEX_NO_MATCH, value, expression); } diff --git a/source/java/org/alfresco/repo/importer/ExportSourceImporter.java b/source/java/org/alfresco/repo/importer/ExportSourceImporter.java index be41b10a38..2d9f3af4e0 100644 --- a/source/java/org/alfresco/repo/importer/ExportSourceImporter.java +++ b/source/java/org/alfresco/repo/importer/ExportSourceImporter.java @@ -27,8 +27,10 @@ package org.alfresco.repo.importer; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.Reader; import java.io.Writer; import java.util.List; @@ -173,12 +175,12 @@ public class ExportSourceImporter implements ImporterJobSPI } File tempFile = TempFileProvider.createTempFile("ExportSourceImporter-", ".xml"); - Writer writer = new BufferedWriter(new FileWriter(tempFile)); + Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "UTF-8")); XMLWriter xmlWriter = createXMLExporter(writer); exportSource.generateExport(xmlWriter); xmlWriter.close(); - Reader reader = new BufferedReader(new FileReader(tempFile)); + Reader reader = new BufferedReader(new InputStreamReader(new FileInputStream(tempFile), "UTF-8")); Location location = new Location(storeRef); location.setPath(path); diff --git a/source/java/org/alfresco/repo/jscript/ScriptUtils.java b/source/java/org/alfresco/repo/jscript/ScriptUtils.java index 28ca5d595a..de917e6a6d 100644 --- a/source/java/org/alfresco/repo/jscript/ScriptUtils.java +++ b/source/java/org/alfresco/repo/jscript/ScriptUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,6 +33,7 @@ import org.alfresco.service.cmr.module.ModuleService; import org.alfresco.service.cmr.module.ModuleDetails; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.util.ISO8601DateFormat; /** * Place for general and miscellaneous utility functions not already found in generic JavaScript. @@ -126,4 +127,37 @@ public final class ScriptUtils extends BaseScopableProcessorExtension } return false; } + + /** + * Format timeInMillis to ISO 8601 formatted string + * + * @param timeInMillis + * @return + */ + public String toISO8601(long timeInMillis) + { + return ISO8601DateFormat.format(new Date(timeInMillis)); + } + + /** + * Format date to ISO 8601 formatted string + * + * @param date + * @return + */ + public String toISO8601(Date date) + { + return ISO8601DateFormat.format(date); + } + + /** + * Parse date from ISO formatted string + * + * @param isoDateString + * @return + */ + public Date fromISO8601(String isoDateString) + { + return ISO8601DateFormat.parse(isoDateString); + } } diff --git a/source/java/org/alfresco/repo/node/db/NodeDaoService.java b/source/java/org/alfresco/repo/node/db/NodeDaoService.java index 730f638e30..1b445742bd 100644 --- a/source/java/org/alfresco/repo/node/db/NodeDaoService.java +++ b/source/java/org/alfresco/repo/node/db/NodeDaoService.java @@ -570,4 +570,10 @@ public interface NodeDaoService @DirtySessionAnnotation(markDirty=true) public void purgeTxn(Long txnId); + + @DirtySessionAnnotation(markDirty=false) + public Long getMinTxnCommitTime(); + + @DirtySessionAnnotation(markDirty=false) + public Long getMaxTxnCommitTime(); } diff --git a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java index 2ad9b88ffd..ad2e06fb37 100644 --- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java +++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -672,6 +672,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements { return new NodeRef.Status( node.getTransaction().getChangeTxnId(), + node.getTransaction().getId(), node.getDeleted()); } } diff --git a/source/java/org/alfresco/repo/node/index/AbstractReindexComponent.java b/source/java/org/alfresco/repo/node/index/AbstractReindexComponent.java index d3a8dbf302..e7a6afc15a 100644 --- a/source/java/org/alfresco/repo/node/index/AbstractReindexComponent.java +++ b/source/java/org/alfresco/repo/node/index/AbstractReindexComponent.java @@ -240,6 +240,12 @@ public abstract class AbstractReindexComponent implements IndexRecovery { try { + // started + if (logger.isDebugEnabled()) + { + logger.debug("Reindex work started: " + this); + } + AuthenticationUtil.pushAuthentication(); // authenticate as the system user AuthenticationUtil.setRunAsUserSystem(); @@ -284,7 +290,7 @@ public abstract class AbstractReindexComponent implements IndexRecovery } } - protected enum InIndex + public enum InIndex { YES, NO, INDETERMINATE; } @@ -348,7 +354,7 @@ public abstract class AbstractReindexComponent implements IndexRecovery * @param txn a specific transaction * @return Returns true if the transaction is definitely in the index */ - protected InIndex isTxnPresentInIndex(final Transaction txn) + public InIndex isTxnPresentInIndex(final Transaction txn) { if (txn == null) { @@ -356,9 +362,9 @@ public abstract class AbstractReindexComponent implements IndexRecovery } final Long txnId = txn.getId(); - if (logger.isDebugEnabled()) + if (logger.isTraceEnabled()) { - logger.debug("Checking for transaction in index: " + txnId); + logger.trace("Checking for transaction in index: " + txnId); } // Check if the txn ID is present in any store's index @@ -398,6 +404,7 @@ public abstract class AbstractReindexComponent implements IndexRecovery { // There were deleted nodes only. Check that all the deleted nodes were // removed from the index otherwise it is out of date. + result = InIndex.YES; for (StoreRef storeRef : storeRefs) { if (!haveNodesBeenRemovedFromIndex(storeRef, txn)) @@ -444,17 +451,17 @@ public abstract class AbstractReindexComponent implements IndexRecovery if (results.length() > 0) { - if (logger.isDebugEnabled()) + if (logger.isTraceEnabled()) { - logger.debug("Index has results for txn " + txnId + " for store " + storeRef); + logger.trace("Index has results for txn " + txnId + " for store " + storeRef); } return true; // there were updates/creates and results for the txn were found } else { - if (logger.isDebugEnabled()) + if (logger.isTraceEnabled()) { - logger.debug("Transaction " + txnId + " not in index for store " + storeRef + ". Possibly out of date."); + logger.trace("Transaction " + txnId + " not in index for store " + storeRef + ". Possibly out of date."); } return false; } @@ -474,9 +481,9 @@ public abstract class AbstractReindexComponent implements IndexRecovery boolean foundNodeRef = false; for (NodeRef nodeRef : nodeRefs) { - if (logger.isDebugEnabled()) + if (logger.isTraceEnabled()) { - logger.debug("Searching for node in index: \n" + + logger.trace("Searching for node in index: \n" + " node: " + nodeRef + "\n" + " txn: " + txnId); } @@ -514,9 +521,9 @@ public abstract class AbstractReindexComponent implements IndexRecovery else { // No nodes found - if (logger.isDebugEnabled()) + if (logger.isTraceEnabled()) { - logger.debug(" --> Node not found (OK)"); + logger.trace(" --> Node not found (OK)"); } } return !foundNodeRef; diff --git a/source/java/org/alfresco/repo/node/index/IndexTransactionTracker.java b/source/java/org/alfresco/repo/node/index/IndexTransactionTracker.java index 2e874601c9..7f3d129b95 100644 --- a/source/java/org/alfresco/repo/node/index/IndexTransactionTracker.java +++ b/source/java/org/alfresco/repo/node/index/IndexTransactionTracker.java @@ -1,18 +1,26 @@ /* - * Copyright (C) 2005-2006 Alfresco, Inc. + * Copyright (C) 2005-2009 Alfresco Software Limited. * - * 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. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" */ package org.alfresco.repo.node.index; @@ -56,6 +64,10 @@ public class IndexTransactionTracker extends AbstractReindexComponent private Map voids; private boolean forceReindex; + private long fromTxnId; + private String statusMsg; + private static final String NO_REINDEX = "No reindex in progress"; + /** * Set the defaults. *