diff --git a/config/alfresco/patch/patch-services-context.xml b/config/alfresco/patch/patch-services-context.xml
index 5745e01e95..a815f61fac 100644
--- a/config/alfresco/patch/patch-services-context.xml
+++ b/config/alfresco/patch/patch-services-context.xml
@@ -2,6 +2,16 @@
- * Patches have a version, e.g. 1.1.1, which is the version of the repo - * after which the patch should be applied. If the repository version is 1.1.2 - * then the patch will not be applied as the repository was created with a newer version - * of the codebase, thereby rendering the patch unecessary. If the repository is at - * version 1.1 then the patch needs to be applied as the codebase of the repository - * is newer than the repository creation. * * @return Returns true if all outstanding patches were applied, or false if the process * was termintated before all patches could be applied. diff --git a/source/java/org/alfresco/repo/admin/patch/PatchServiceImpl.java b/source/java/org/alfresco/repo/admin/patch/PatchServiceImpl.java index b33d70e0dc..9d87134f1e 100644 --- a/source/java/org/alfresco/repo/admin/patch/PatchServiceImpl.java +++ b/source/java/org/alfresco/repo/admin/patch/PatchServiceImpl.java @@ -188,6 +188,9 @@ public class PatchServiceImpl implements PatchService success = false; } } + + Descriptor serverDescriptor = descriptorService.getServerDescriptor(); + String server = (serverDescriptor.getVersion() + " - " + serverDescriptor.getEdition()); // create a record for the execution appliedPatch = patchDaoService.newAppliedPatch(patch.getId()); @@ -197,6 +200,7 @@ public class PatchServiceImpl implements PatchService appliedPatch.setFixesToSchema(patch.getFixesToSchema()); appliedPatch.setTargetSchema(patch.getTargetSchema()); // the schema the server is expecting appliedPatch.setAppliedToSchema(repoDescriptor.getSchema()); // the old schema of the repo + appliedPatch.setAppliedToServer(server); // the current version and label of the server appliedPatch.setAppliedOnDate(new Date()); // the date applied appliedPatch.setSucceeded(success); // whether or not the patch succeeded appliedPatch.setReport(report); // additional, human-readable, status diff --git a/source/java/org/alfresco/repo/admin/patch/impl/SavedSearchFolderPatch.java b/source/java/org/alfresco/repo/admin/patch/impl/SavedSearchFolderPatch.java new file mode 100644 index 0000000000..978a8507bb --- /dev/null +++ b/source/java/org/alfresco/repo/admin/patch/impl/SavedSearchFolderPatch.java @@ -0,0 +1,210 @@ +/* + * 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.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.admin.patch.AbstractPatch; +import org.alfresco.repo.importer.ImporterBootstrap; +import org.alfresco.service.cmr.admin.PatchException; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; + +/** + * Ensures that the savedsearches folder is present. + *
+ * This uses the bootstrap importer to get the paths to look for. If not present, + * the required structures are created. + *
+ * This class should be replaced with a more generic ImporterPatch
+ * that can do conditional importing into given locations.
+ *
+ * @author Derek Hulley
+ */
+public class SavedSearchFolderPatch extends AbstractPatch
+{
+ private static final String MSG_EXISTS = "The saved searches folder already exists: %s.";
+ private static final String MSG_CREATED = "The saved searches folder successfully created: %s.";
+
+ private static final String PROPERTY_COMPANY_HOME_CHILDNAME = "spaces.company_home.childname";
+ private static final String PROPERTY_DICTIONARY_CHILDNAME = "spaces.dictionary.childname";
+ private static final String PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME = "spaces.savedsearches.childname";
+ private static final String PROPERTY_SAVED_SEARCHES_FOLDER_NAME = "spaces.savedsearches.name";
+ private static final String PROPERTY_SAVED_SEARCHES_FOLDER_DESCRIPTION = "spaces.savedsearches.description";
+ private static final String PROPERTY_ICON = "space-icon-default";
+
+ private ImporterBootstrap importerBootstrap;
+ private NamespaceService namespaceService;
+ private SearchService searchService;
+ private NodeService nodeService;
+
+ public void setImporterBootstrap(ImporterBootstrap importerBootstrap)
+ {
+ this.importerBootstrap = importerBootstrap;
+ }
+
+ public void setNamespaceService(NamespaceService namespaceService)
+ {
+ this.namespaceService = namespaceService;
+ }
+
+ public void setSearchService(SearchService searchService)
+ {
+ this.searchService = searchService;
+ }
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ @Override
+ protected String applyInternal() throws Exception
+ {
+ if (importerBootstrap == null)
+ {
+ throw new PatchException("'importerBootstrap' property has not been set");
+ }
+ else if (namespaceService == null)
+ {
+ throw new PatchException("'namespaceService' property has not been set");
+ }
+ else if (searchService == null)
+ {
+ throw new PatchException("'searchService' property has not been set");
+ }
+ else if (nodeService == null)
+ {
+ throw new PatchException("'nodeService' property has not been set");
+ }
+
+ // get the node store that we must work against
+ StoreRef storeRef = importerBootstrap.getStoreRef();
+ if (storeRef == null)
+ {
+ throw new PatchException("Bootstrap store has not been set");
+ }
+ NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
+
+ Properties configuration = importerBootstrap.getConfiguration();
+ // get the association names that form the path
+ String companyHomeChildName = configuration.getProperty(PROPERTY_COMPANY_HOME_CHILDNAME);
+ if (companyHomeChildName == null || companyHomeChildName.length() == 0)
+ {
+ throw new PatchException("Bootstrap property '" + PROPERTY_COMPANY_HOME_CHILDNAME + "' is not present");
+ }
+ String dictionaryChildName = configuration.getProperty(PROPERTY_DICTIONARY_CHILDNAME);
+ if (dictionaryChildName == null || dictionaryChildName.length() == 0)
+ {
+ throw new PatchException("Bootstrap property '" + PROPERTY_DICTIONARY_CHILDNAME + "' is not present");
+ }
+ String savedSearchesChildName = configuration.getProperty(PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME);
+ if (savedSearchesChildName == null || savedSearchesChildName.length() == 0)
+ {
+ throw new PatchException("Bootstrap property '" + PROPERTY_SAVED_SEARCHES_FOLDER_CHILDNAME + "' is not present");
+ }
+
+ // build the search string to get the dictionary node
+ StringBuilder sb = new StringBuilder(512);
+ sb.append("/").append(companyHomeChildName)
+ .append("/").append(dictionaryChildName);
+ String xpath = sb.toString();
+ // get the dictionary node
+ List