mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V1.4 to HEAD
svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@3987 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4133 . Removed LicenseComponent reference from projects\repository\source\java\org\alfresco\repo\descriptor\DescriptorServiceImpl.java git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4135 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -22,6 +22,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.node.integrity.IntegrityChecker;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.transaction.TransactionUtil;
|
||||
import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
|
||||
@@ -329,6 +330,9 @@ public abstract class AbstractPatch implements Patch
|
||||
{
|
||||
public String doWork() throws Exception
|
||||
{
|
||||
// downgrade integrity checking
|
||||
IntegrityChecker.setWarnInTransaction();
|
||||
|
||||
String report = applyInternal();
|
||||
// done
|
||||
return report;
|
||||
@@ -389,7 +393,8 @@ public abstract class AbstractPatch implements Patch
|
||||
|
||||
/**
|
||||
* This method does the work. All transactions and thread-safety will be taken care of by this class.
|
||||
* Any exception will result in the transaction being rolled back.
|
||||
* Any exception will result in the transaction being rolled back. Integrity checks are downgraded
|
||||
* for the duration of the transaction.
|
||||
*
|
||||
* @return Returns the report (only success messages).
|
||||
* @see #apply()
|
||||
|
@@ -21,11 +21,10 @@ import java.util.List;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.util.AbstractLifecycleBean;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
|
||||
/**
|
||||
* This component is responsible for ensuring that patches are applied
|
||||
@@ -33,7 +32,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class PatchExecuter implements ApplicationListener
|
||||
public class PatchExecuter extends AbstractLifecycleBean
|
||||
{
|
||||
private static final String MSG_CHECKING = "patch.executer.checking";
|
||||
private static final String MSG_NO_PATCHES_REQUIRED = "patch.executer.no_patches_required";
|
||||
@@ -101,16 +100,16 @@ public class PatchExecuter implements ApplicationListener
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
|
||||
*/
|
||||
public void onApplicationEvent(ApplicationEvent event)
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
if (event instanceof ContextRefreshedEvent)
|
||||
{
|
||||
applyOutstandingPatches();
|
||||
}
|
||||
applyOutstandingPatches();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event)
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* 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.util.List;
|
||||
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.domain.DbAccessControlEntry;
|
||||
import org.alfresco.repo.domain.DbPermission;
|
||||
import org.alfresco.repo.domain.hibernate.DbPermissionImpl;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Provides common functionality to change a permission type and/or name.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public abstract class AbstractPermissionChangePatch extends AbstractPatch
|
||||
{
|
||||
private HibernateHelper helper;
|
||||
|
||||
public AbstractPermissionChangePatch()
|
||||
{
|
||||
helper = new HibernateHelper();
|
||||
}
|
||||
|
||||
public void setSessionFactory(SessionFactory sessionFactory)
|
||||
{
|
||||
this.helper.setSessionFactory(sessionFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to rename (move) a permission. This involves checking for the existence of the
|
||||
* new permission and then moving all the entries to point to the new permission.
|
||||
*
|
||||
* @param oldTypeQName the old permission type
|
||||
* @param oldName the old permission name
|
||||
* @param newTypeQName the new permission type
|
||||
* @param newName the new permission name
|
||||
* @return Returns the number of permission entries modified
|
||||
*/
|
||||
protected int renamePermission(QName oldTypeQName, String oldName, QName newTypeQName, String newName)
|
||||
{
|
||||
return helper.createAndUpdatePermission(oldTypeQName, oldName, newTypeQName, newName);
|
||||
}
|
||||
|
||||
/** Helper to get a permission entity */
|
||||
private static class GetPermissionCallback implements HibernateCallback
|
||||
{
|
||||
private QName typeQName;
|
||||
private String name;
|
||||
public GetPermissionCallback(QName typeQName, String name)
|
||||
{
|
||||
this.typeQName = typeQName;
|
||||
this.name = name;
|
||||
}
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
// flush any outstanding entities
|
||||
session.flush();
|
||||
|
||||
Query query = session.getNamedQuery(HibernateHelper.QUERY_GET_PERMISSION);
|
||||
query.setParameter("permissionTypeQName", typeQName)
|
||||
.setString("permissionName", name);
|
||||
return query.uniqueResult();
|
||||
}
|
||||
}
|
||||
|
||||
private static class HibernateHelper extends HibernateDaoSupport
|
||||
{
|
||||
private static final String QUERY_GET_PERMISSION = "permission.GetPermission";
|
||||
private static final String QUERY_GET_ENTRIES_TO_CHANGE = "permission.patch.GetAccessControlEntriesToChangePermissionOn";
|
||||
|
||||
public int createAndUpdatePermission(
|
||||
final QName oldTypeQName,
|
||||
final String oldName,
|
||||
final QName newTypeQName,
|
||||
final String newName)
|
||||
{
|
||||
if (oldTypeQName.equals(newTypeQName) && oldName.equals(newName))
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot move permission to itself: " + oldTypeQName + "-" + oldName);
|
||||
}
|
||||
|
||||
HibernateCallback getNewPermissionCallback = new GetPermissionCallback(newTypeQName, newName);
|
||||
DbPermission permission = (DbPermission) getHibernateTemplate().execute(getNewPermissionCallback);
|
||||
if (permission == null)
|
||||
{
|
||||
// create the permission
|
||||
permission = new DbPermissionImpl();
|
||||
permission.setTypeQname(newTypeQName);
|
||||
permission.setName(newName);
|
||||
// save
|
||||
getHibernateTemplate().save(permission);
|
||||
}
|
||||
final DbPermission newPermission = permission;
|
||||
// now update all entries that refer to the old permission
|
||||
HibernateCallback updateEntriesCallback = new HibernateCallback()
|
||||
{
|
||||
private static final int MAX_RESULTS = 1000;
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object doInHibernate(Session session)
|
||||
{
|
||||
int count = 0;
|
||||
while (true)
|
||||
{
|
||||
// flush any outstanding entities
|
||||
session.flush();
|
||||
|
||||
Query query = session.getNamedQuery(HibernateHelper.QUERY_GET_ENTRIES_TO_CHANGE);
|
||||
query.setParameter("oldTypeQName", oldTypeQName)
|
||||
.setParameter("oldName", oldName)
|
||||
.setMaxResults(MAX_RESULTS);
|
||||
List<DbAccessControlEntry> entries = (List<DbAccessControlEntry>) query.list();
|
||||
// if there are no results, then we're done
|
||||
if (entries.size() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
for (DbAccessControlEntry entry : entries)
|
||||
{
|
||||
entry.setPermission(newPermission);
|
||||
count++;
|
||||
session.evict(entry);
|
||||
}
|
||||
// flush and evict all the entries
|
||||
session.flush();
|
||||
for (DbAccessControlEntry entry : entries)
|
||||
{
|
||||
session.evict(entry);
|
||||
}
|
||||
// next set of results
|
||||
}
|
||||
// done
|
||||
return count;
|
||||
}
|
||||
};
|
||||
int updateCount = (Integer) getHibernateTemplate().execute(updateEntriesCallback);
|
||||
// now delete the old permission
|
||||
HibernateCallback getOldPermissionCallback = new GetPermissionCallback(oldTypeQName, oldName);
|
||||
DbPermission oldPermission = (DbPermission) getHibernateTemplate().execute(getOldPermissionCallback);
|
||||
if (oldPermission != null)
|
||||
{
|
||||
getHibernateTemplate().delete(oldPermission);
|
||||
}
|
||||
// done
|
||||
return updateCount;
|
||||
}
|
||||
}
|
||||
}
|
@@ -54,6 +54,10 @@ public class ActionRuleDecouplingPatch extends AbstractPatch
|
||||
for (NodeRef origRuleNodeRef : resultSet.getNodeRefs())
|
||||
{
|
||||
// Check that this rule need updated
|
||||
if (!this.nodeService.exists(origRuleNodeRef))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Map<QName, Serializable> origProperties = this.nodeService.getProperties(origRuleNodeRef);
|
||||
if (origProperties.containsKey(RuleModel.PROP_EXECUTE_ASYNC) == false)
|
||||
{
|
||||
@@ -79,21 +83,21 @@ public class ActionRuleDecouplingPatch extends AbstractPatch
|
||||
Map<QName, Serializable> newProperties = this.nodeService.getProperties(newRuleNodeRef);
|
||||
|
||||
// Set the rule type, execute async and applyToChildren properties on the rule
|
||||
String ruleType = (String)origProperties.get(RuleModel.PROP_RULE_TYPE);
|
||||
Serializable ruleType = origProperties.get(RuleModel.PROP_RULE_TYPE);
|
||||
origProperties.remove(RuleModel.PROP_RULE_TYPE);
|
||||
newProperties.put(RuleModel.PROP_RULE_TYPE, ruleType);
|
||||
Boolean executeAsync = (Boolean)origProperties.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY);
|
||||
Serializable executeAsync = origProperties.get(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY);
|
||||
origProperties.remove(ActionModel.PROP_EXECUTE_ASYNCHRONOUSLY);
|
||||
newProperties.put(RuleModel.PROP_EXECUTE_ASYNC, executeAsync);
|
||||
Boolean applyToChildren = (Boolean)origProperties.get(RuleModel.PROP_APPLY_TO_CHILDREN);
|
||||
Serializable applyToChildren = origProperties.get(RuleModel.PROP_APPLY_TO_CHILDREN);
|
||||
origProperties.remove(RuleModel.PROP_APPLY_TO_CHILDREN);
|
||||
newProperties.put(RuleModel.PROP_APPLY_TO_CHILDREN, applyToChildren);
|
||||
origProperties.remove(QName.createQName(RuleModel.RULE_MODEL_URI, "owningNodeRef"));
|
||||
|
||||
// Move the action and description values from the composite action onto the rule
|
||||
String title = (String)origProperties.get(ActionModel.PROP_ACTION_TITLE);
|
||||
Serializable title = origProperties.get(ActionModel.PROP_ACTION_TITLE);
|
||||
origProperties.remove(ActionModel.PROP_ACTION_TITLE);
|
||||
String description = (String)origProperties.get(ActionModel.PROP_ACTION_DESCRIPTION);
|
||||
Serializable description = origProperties.get(ActionModel.PROP_ACTION_DESCRIPTION);
|
||||
origProperties.remove(ActionModel.PROP_ACTION_DESCRIPTION);
|
||||
newProperties.put(ContentModel.PROP_TITLE, title);
|
||||
newProperties.put(ContentModel.PROP_DESCRIPTION, description);
|
||||
|
@@ -16,33 +16,40 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.service.cmr.admin.PatchException;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Roles defined in permissionsDefinition.xml moved from <b>cm:content</b> to <b>sys:base</b>.
|
||||
* This effects the data stored in the <b>node_perm_entry</b> table.
|
||||
* <p>
|
||||
* <b>WILL NOT EXECUTE ANYMORE</b>
|
||||
* This effects the data stored in the <b>permission</b> table.
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class ContentPermissionPatch extends AbstractPatch
|
||||
public class ContentPermissionPatch extends AbstractPermissionChangePatch
|
||||
{
|
||||
private static final String MSG_UPGRADE = "patch.contentPermission.upgrade";
|
||||
|
||||
public ContentPermissionPatch()
|
||||
{
|
||||
}
|
||||
|
||||
public void setSessionFactory(SessionFactory sessionFactory)
|
||||
{
|
||||
}
|
||||
private static final String MSG_SUCCESS = "patch.contentPermission.result";
|
||||
|
||||
private static final QName TYPE_QNAME_OLD = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "content");
|
||||
private static final QName TYPE_QNAME_NEW = QName.createQName(NamespaceService.SYSTEM_MODEL_1_0_URI, "base");
|
||||
private static final String[] NAMES = new String[] {"Execute", "ReadContent", "WriteContent", "ExecuteContent"};
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
throw new PatchException(MSG_UPGRADE);
|
||||
int updateCount = 0;
|
||||
for (String permissionName : NAMES)
|
||||
{
|
||||
updateCount += super.renamePermission(
|
||||
ContentPermissionPatch.TYPE_QNAME_OLD,
|
||||
permissionName,
|
||||
ContentPermissionPatch.TYPE_QNAME_NEW,
|
||||
permissionName);
|
||||
}
|
||||
|
||||
// build the result message
|
||||
String msg = I18NUtil.getMessage(MSG_SUCCESS, updateCount);
|
||||
// done
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
@@ -16,35 +16,42 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.service.cmr.admin.PatchException;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* The roles defined in permissionsDefinition.xml moved from <b>cm:folder</b> to <b>cm:cmobject</b>.
|
||||
* This effects the data stored in the <b>node_perm_entry</b> table.
|
||||
* This effects the data stored in the <b>permission</b> table.
|
||||
* <p>
|
||||
* JIRA: {@link http://www.alfresco.org/jira/browse/AR-344 AR-344}
|
||||
* <p>
|
||||
* <b>WILL NOT EXECUTE ANYMORE</b>
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class PermissionDataPatch extends AbstractPatch
|
||||
public class PermissionDataPatch extends AbstractPermissionChangePatch
|
||||
{
|
||||
private static final String MSG_UPGRADE = "patch.updatePermissionData.upgrade";
|
||||
|
||||
public PermissionDataPatch()
|
||||
{
|
||||
}
|
||||
|
||||
public void setSessionFactory(SessionFactory sessionFactory)
|
||||
{
|
||||
}
|
||||
private static final String MSG_SUCCESS = "patch.updatePermissionData.result";
|
||||
|
||||
private static final QName TYPE_QNAME_OLD = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "folder");
|
||||
private static final QName TYPE_QNAME_NEW = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "cmobject");
|
||||
private static final String[] NAMES = new String[] {"Coordinator", "Contributor", "Editor", "Guest"};
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
throw new PatchException(MSG_UPGRADE);
|
||||
int updateCount = 0;
|
||||
for (String permissionName : NAMES)
|
||||
{
|
||||
updateCount += super.renamePermission(
|
||||
PermissionDataPatch.TYPE_QNAME_OLD,
|
||||
permissionName,
|
||||
PermissionDataPatch.TYPE_QNAME_NEW,
|
||||
permissionName);
|
||||
}
|
||||
|
||||
// build the result message
|
||||
String msg = I18NUtil.getMessage(MSG_SUCCESS, updateCount);
|
||||
// done
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
@@ -16,32 +16,27 @@
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.service.cmr.admin.PatchException;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
|
||||
/**
|
||||
* The permission 'Guest' has been renamed to 'Consumer'.
|
||||
* <p>
|
||||
* <b>WILL NOT EXECUTE ANYMORE</b>
|
||||
*
|
||||
* @author David Caruana
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
public class UpdateGuestPermissionPatch extends AbstractPatch
|
||||
public class UpdateGuestPermissionPatch extends AbstractPermissionChangePatch
|
||||
{
|
||||
private static final String MSG_UPGRADE = "patch.updateGuestPermission.upgrade";
|
||||
|
||||
public UpdateGuestPermissionPatch()
|
||||
{
|
||||
}
|
||||
|
||||
public void setSessionFactory(SessionFactory sessionFactory)
|
||||
{
|
||||
}
|
||||
private static final String MSG_SUCCESS = "patch.updateGuestPermission.result";
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
throw new PatchException(MSG_UPGRADE);
|
||||
int updateCount = super.renamePermission(ContentModel.TYPE_CMOBJECT, "Guest", ContentModel.TYPE_CMOBJECT, "Consumer");
|
||||
|
||||
// build the result message
|
||||
String msg = I18NUtil.getMessage(MSG_SUCCESS, updateCount);
|
||||
// done
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,573 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.alfresco.repo.admin.patch.util;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.action.ActionModel;
|
||||
import org.alfresco.repo.rule.RuleModel;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.util.GUID;
|
||||
import org.dom4j.io.OutputFormat;
|
||||
import org.dom4j.io.XMLWriter;
|
||||
import org.xml.sax.helpers.AttributesImpl;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
|
||||
/**
|
||||
* Updates a XML import file to be compatable with the current version of the repository.
|
||||
*
|
||||
* @author royw
|
||||
*/
|
||||
public class ImportFileUpdater
|
||||
{
|
||||
/** Indent size **/
|
||||
private static int INDENT_SIZE = 2;
|
||||
|
||||
/** The destination export version number **/
|
||||
private static String EXPORT_VERSION = "1.4.0";
|
||||
|
||||
/** Element names **/
|
||||
private static String NAME_EXPORTER_VERSION = "exporterVersion";
|
||||
private static String NAME_RULE = "rule";
|
||||
|
||||
/** The current import version number **/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* Updates the passed import file into the equivalent 1.4 format.
|
||||
*
|
||||
* @param source the source import file
|
||||
* @param destination the destination import file
|
||||
*/
|
||||
public void updateImportFile(String source, String destination)
|
||||
{
|
||||
XmlPullParser reader = getReader(source);
|
||||
XMLWriter writer = getWriter(destination);
|
||||
|
||||
try
|
||||
{
|
||||
// Start the documentation
|
||||
writer.startDocument();
|
||||
|
||||
// Start reading the document
|
||||
int eventType = reader.getEventType();
|
||||
while (eventType != XmlPullParser.END_DOCUMENT)
|
||||
{
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer, new OutputChildren());
|
||||
}
|
||||
eventType = reader.next();
|
||||
}
|
||||
|
||||
// End and close the document
|
||||
writer.endDocument();
|
||||
writer.close();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to update import file.", exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reader for the source import file
|
||||
*
|
||||
* @param source the source import file
|
||||
* @return the XML pull parser used to read the file
|
||||
*/
|
||||
private XmlPullParser getReader(String source)
|
||||
{
|
||||
try
|
||||
{
|
||||
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
|
||||
factory.setNamespaceAware(true);
|
||||
|
||||
XmlPullParser xpp = factory.newPullParser();
|
||||
xpp.setInput(new FileReader(source));
|
||||
|
||||
return xpp;
|
||||
}
|
||||
catch (XmlPullParserException exception)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to update import file.", exception);
|
||||
}
|
||||
catch (FileNotFoundException fileNotFound)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("The source file could not be loaded.", fileNotFound);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the writer for the import file
|
||||
*
|
||||
* @param destination the destination XML import file
|
||||
* @return the XML writer
|
||||
*/
|
||||
private XMLWriter getWriter(String destination)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Define output format
|
||||
OutputFormat format = OutputFormat.createPrettyPrint();
|
||||
format.setNewLineAfterDeclaration(false);
|
||||
format.setIndentSize(INDENT_SIZE);
|
||||
format.setEncoding("UTF-8");
|
||||
|
||||
return new XMLWriter(new FileOutputStream(destination), format);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to create XML writer.", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private void outputCurrentElement(XmlPullParser reader, XMLWriter writer, Work work)
|
||||
throws Exception
|
||||
{
|
||||
outputCurrentElement(reader, writer, work, true);
|
||||
}
|
||||
|
||||
private void outputCurrentElement(XmlPullParser reader, XMLWriter writer, Work work, boolean checkForCallbacks)
|
||||
throws Exception
|
||||
{
|
||||
if (checkForCallbacks == false || checkForCallbacks(reader, writer) == false)
|
||||
{
|
||||
// Get the name details of the element
|
||||
String name = reader.getName();
|
||||
String namespace = reader.getNamespace();
|
||||
String prefix = reader.getPrefix();
|
||||
|
||||
// Sort out namespaces
|
||||
Map<String, String> nss = new HashMap<String, String>();
|
||||
int nsStart = reader.getNamespaceCount(reader.getDepth()-1);
|
||||
int nsEnd = reader.getNamespaceCount(reader.getDepth());
|
||||
for (int i = nsStart; i < nsEnd; i++)
|
||||
{
|
||||
String nsPrefix = reader.getNamespacePrefix(i);
|
||||
String ns = reader.getNamespaceUri(i);
|
||||
nss.put(nsPrefix, ns);
|
||||
}
|
||||
|
||||
// Sort out attributes
|
||||
AttributesImpl attributes = new AttributesImpl();
|
||||
for (int i = 0; i < reader.getAttributeCount(); i++)
|
||||
{
|
||||
String attributeName = reader.getAttributeName(i);
|
||||
String attributeNamespace = reader.getAttributeNamespace(i);
|
||||
String attributePrefix = reader.getAttributePrefix(i);
|
||||
String attributeType = reader.getAttributeType(i);
|
||||
String attributeValue = reader.getAttributeValue(i);
|
||||
|
||||
attributes.addAttribute(attributeNamespace, attributeName, attributePrefix+":"+attributeName, attributeType, attributeValue);
|
||||
}
|
||||
|
||||
// Start the namespace prefixes
|
||||
for (Map.Entry<String, String> entry : nss.entrySet())
|
||||
{
|
||||
writer.startPrefixMapping(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
// Write the start of the element
|
||||
writer.startElement(namespace, name, prefix+":"+name, attributes);
|
||||
|
||||
// Do the work
|
||||
work.doWork(reader, writer);
|
||||
|
||||
// Write the end of the element
|
||||
writer.endElement(namespace, name, prefix+":"+name);
|
||||
|
||||
// End the namespace prefixes
|
||||
for (String nsPrefix : nss.keySet())
|
||||
{
|
||||
writer.endPrefixMapping(nsPrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkForCallbacks(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception
|
||||
{
|
||||
boolean result = false;
|
||||
if (reader.getName().equals(NAME_EXPORTER_VERSION) == true)
|
||||
{
|
||||
new ImportVersionLabelCallback().doCallback(reader, writer);
|
||||
result = true;
|
||||
}
|
||||
else if (reader.getName().equals(NAME_RULE) == true)
|
||||
{
|
||||
if (this.version.startsWith("1.3") == true)
|
||||
{
|
||||
new RuleCallback().doCallback(reader, writer);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private interface Work
|
||||
{
|
||||
void doWork(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception;
|
||||
}
|
||||
|
||||
private class OutputChildren implements Work
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception
|
||||
{
|
||||
// Deal with the contents of the tag
|
||||
int eventType = reader.getEventType();
|
||||
while (eventType != XmlPullParser.END_TAG)
|
||||
{
|
||||
eventType = reader.next();
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer, new OutputChildren());
|
||||
}
|
||||
else if (eventType == XmlPullParser.TEXT)
|
||||
{
|
||||
// Write the text to the output file
|
||||
writer.write(reader.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class IgnoreChildren implements Work
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception
|
||||
{
|
||||
int eventType = reader.getEventType();
|
||||
while (eventType != XmlPullParser.END_TAG)
|
||||
{
|
||||
eventType = reader.next();
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
doWork(reader, writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private interface ImportUpdaterCallback
|
||||
{
|
||||
void doCallback(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception;
|
||||
}
|
||||
|
||||
private class ImportVersionLabelCallback implements ImportUpdaterCallback
|
||||
{
|
||||
public void doCallback(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer,
|
||||
new Work()
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer) throws Exception
|
||||
{
|
||||
reader.next();
|
||||
ImportFileUpdater.this.version = reader.getText();
|
||||
writer.write(EXPORT_VERSION);
|
||||
reader.next();
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
private class RuleCallback implements ImportUpdaterCallback
|
||||
{
|
||||
public void doCallback(XmlPullParser reader, XMLWriter writer)
|
||||
throws Exception
|
||||
{
|
||||
// Get the name details of the element
|
||||
String name = reader.getName();
|
||||
String namespace = reader.getNamespace();
|
||||
String prefix = reader.getPrefix();
|
||||
|
||||
// Rename the child assoc appropriately
|
||||
AttributesImpl attributes = new AttributesImpl();
|
||||
String attributeName = reader.getAttributeName(0);
|
||||
String attributeNamespace = reader.getAttributeNamespace(0);
|
||||
String attributePrefix = reader.getAttributePrefix(0);
|
||||
String attributeType = reader.getAttributeType(0);
|
||||
String attributeValue = reader.getAttributeValue(0) + GUID.generate();
|
||||
attributes.addAttribute(attributeNamespace, attributeName, attributePrefix+":"+attributeName, attributeType, attributeValue);
|
||||
|
||||
// Output the rules element
|
||||
writer.startElement(namespace, name, prefix+":"+name, attributes);
|
||||
|
||||
int eventType = reader.getEventType();
|
||||
while (eventType != XmlPullParser.END_TAG)
|
||||
{
|
||||
eventType = reader.next();
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
String childName = reader.getName();
|
||||
if (childName.equals("aspects") == true)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer,
|
||||
new Work()
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer) throws Exception
|
||||
{
|
||||
// Add titled aspect
|
||||
writer.startElement(
|
||||
ContentModel.ASPECT_TITLED.getNamespaceURI(),
|
||||
ContentModel.ASPECT_TITLED.getLocalName(),
|
||||
NamespaceService.CONTENT_MODEL_PREFIX + ":" + ContentModel.ASPECT_TITLED.getLocalName(),
|
||||
new AttributesImpl());
|
||||
writer.endElement(
|
||||
ContentModel.ASPECT_TITLED.getNamespaceURI(),
|
||||
ContentModel.ASPECT_TITLED.getLocalName(),
|
||||
NamespaceService.CONTENT_MODEL_PREFIX + ":" + ContentModel.ASPECT_TITLED.getLocalName());
|
||||
|
||||
// Read the rest of the elements and output
|
||||
int eventType = reader.getEventType();
|
||||
while (eventType != XmlPullParser.END_TAG)
|
||||
{
|
||||
eventType = reader.next();
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer, new OutputChildren());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}, false);
|
||||
}
|
||||
else if (childName.equals("properties") == true)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer,
|
||||
new Work()
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer) throws Exception
|
||||
{
|
||||
int eventType = reader.getEventType();
|
||||
while (eventType != XmlPullParser.END_TAG)
|
||||
{
|
||||
eventType = reader.next();
|
||||
if (eventType == XmlPullParser.START_TAG)
|
||||
{
|
||||
String propName = reader.getName();
|
||||
if (propName.equals("actionDescription") == true)
|
||||
{
|
||||
writer.startElement(
|
||||
ContentModel.PROP_DESCRIPTION.getNamespaceURI(),
|
||||
ContentModel.PROP_DESCRIPTION.getLocalName(),
|
||||
NamespaceService.CONTENT_MODEL_PREFIX + ":" + ContentModel.PROP_DESCRIPTION.getLocalName(),
|
||||
new AttributesImpl());
|
||||
|
||||
// Output the value within
|
||||
new OutputChildren().doWork(reader, writer);
|
||||
|
||||
writer.endElement(
|
||||
ContentModel.PROP_DESCRIPTION.getNamespaceURI(),
|
||||
ContentModel.PROP_DESCRIPTION.getLocalName(),
|
||||
NamespaceService.CONTENT_MODEL_PREFIX + ":" + ContentModel.PROP_DESCRIPTION.getLocalName());
|
||||
eventType = reader.next();
|
||||
|
||||
}
|
||||
else if (propName.equals("actionTitle") == true)
|
||||
{
|
||||
writer.startElement(
|
||||
ContentModel.PROP_TITLE.getNamespaceURI(),
|
||||
ContentModel.PROP_TITLE.getLocalName(),
|
||||
NamespaceService.CONTENT_MODEL_PREFIX + ":" + ContentModel.PROP_TITLE.getLocalName(),
|
||||
new AttributesImpl());
|
||||
|
||||
// Output the value within
|
||||
new OutputChildren().doWork(reader, writer);
|
||||
|
||||
writer.endElement(
|
||||
ContentModel.PROP_TITLE.getNamespaceURI(),
|
||||
ContentModel.PROP_TITLE.getLocalName(),
|
||||
NamespaceService.CONTENT_MODEL_PREFIX + ":" + ContentModel.PROP_TITLE.getLocalName());
|
||||
eventType = reader.next();
|
||||
}
|
||||
else if (propName.equals("executeAsynchronously") == true)
|
||||
{
|
||||
writer.startElement(
|
||||
RuleModel.PROP_EXECUTE_ASYNC.getNamespaceURI(),
|
||||
RuleModel.PROP_EXECUTE_ASYNC.getLocalName(),
|
||||
RuleModel.RULE_MODEL_PREFIX + ":" + RuleModel.PROP_EXECUTE_ASYNC.getLocalName(),
|
||||
new AttributesImpl());
|
||||
|
||||
// Output the value within
|
||||
new OutputChildren().doWork(reader, writer);
|
||||
|
||||
writer.endElement(
|
||||
RuleModel.PROP_EXECUTE_ASYNC.getNamespaceURI(),
|
||||
RuleModel.PROP_EXECUTE_ASYNC.getLocalName(),
|
||||
RuleModel.RULE_MODEL_PREFIX + ":" + RuleModel.PROP_EXECUTE_ASYNC.getLocalName());
|
||||
eventType = reader.next();
|
||||
}
|
||||
else if (propName.equals("ruleType") == true)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer,
|
||||
new Work()
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer) throws Exception
|
||||
{
|
||||
// Output the elements that contain a multi values property
|
||||
writer.startElement(NamespaceService.REPOSITORY_VIEW_1_0_URI, "values", "view:values", new AttributesImpl());
|
||||
writer.startElement(NamespaceService.REPOSITORY_VIEW_1_0_URI, "value", "view:value", new AttributesImpl());
|
||||
|
||||
// Output the value within
|
||||
new OutputChildren().doWork(reader, writer);
|
||||
|
||||
// End the multi values elements
|
||||
writer.endElement(NamespaceService.REPOSITORY_VIEW_PREFIX, "value", "view:value");
|
||||
writer.endElement(NamespaceService.REPOSITORY_VIEW_PREFIX, "values", "view:values");
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
else if (propName.equals("definitionName") == true)
|
||||
{
|
||||
// Skip past next end
|
||||
while (eventType != XmlPullParser.END_TAG)
|
||||
{
|
||||
eventType = reader.next();
|
||||
}
|
||||
eventType = reader.next();
|
||||
}
|
||||
else
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer, new OutputChildren());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output value for the disabled property
|
||||
writer.startElement(
|
||||
RuleModel.PROP_DISABLED.getNamespaceURI(),
|
||||
RuleModel.PROP_DISABLED.getLocalName(),
|
||||
RuleModel.RULE_MODEL_PREFIX + ":" + RuleModel.PROP_DISABLED.getLocalName(),
|
||||
new AttributesImpl());
|
||||
writer.write("false");
|
||||
writer.endElement(
|
||||
RuleModel.PROP_DISABLED.getNamespaceURI(),
|
||||
RuleModel.PROP_DISABLED.getLocalName(),
|
||||
RuleModel.RULE_MODEL_PREFIX + ":" + RuleModel.PROP_DISABLED.getLocalName());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
else if (childName.equals("associations") == true)
|
||||
{
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer,
|
||||
new Work()
|
||||
{
|
||||
public void doWork(XmlPullParser reader, XMLWriter writer) throws Exception
|
||||
{
|
||||
// <rule:action>
|
||||
writer.startElement(
|
||||
RuleModel.ASSOC_ACTION.getNamespaceURI(),
|
||||
RuleModel.ASSOC_ACTION.getLocalName(),
|
||||
RuleModel.RULE_MODEL_PREFIX + ":" + RuleModel.ASSOC_ACTION.getLocalName(),
|
||||
new AttributesImpl());
|
||||
|
||||
// <act:compositeaction view:childName="rule:action">
|
||||
AttributesImpl attributes = new AttributesImpl();
|
||||
attributes.addAttribute(NamespaceService.REPOSITORY_VIEW_1_0_URI, "childName", "view:childName", null, "rule:action");
|
||||
writer.startElement(
|
||||
ActionModel.TYPE_COMPOSITE_ACTION.getNamespaceURI(),
|
||||
ActionModel.TYPE_COMPOSITE_ACTION.getLocalName(),
|
||||
ActionModel.ACTION_MODEL_PREFIX+ ":" + ActionModel.TYPE_COMPOSITE_ACTION.getLocalName(),
|
||||
attributes);
|
||||
|
||||
// <view:properties>
|
||||
writer.startElement(
|
||||
NamespaceService.REPOSITORY_VIEW_1_0_URI,
|
||||
"properties",
|
||||
"view:properties",
|
||||
new AttributesImpl());
|
||||
|
||||
// <act:definitionName>composite-action</definitionName>
|
||||
writer.startElement(
|
||||
ActionModel.PROP_DEFINITION_NAME.getNamespaceURI(),
|
||||
ActionModel.PROP_DEFINITION_NAME.getLocalName(),
|
||||
ActionModel.ACTION_MODEL_PREFIX + ":" + ActionModel.PROP_DEFINITION_NAME.getLocalName(),
|
||||
new AttributesImpl());
|
||||
writer.write("composite-action");
|
||||
writer.endElement(
|
||||
ActionModel.PROP_DEFINITION_NAME.getNamespaceURI(),
|
||||
ActionModel.PROP_DEFINITION_NAME.getLocalName(),
|
||||
ActionModel.ACTION_MODEL_PREFIX + ":" + ActionModel.PROP_DEFINITION_NAME.getLocalName());
|
||||
|
||||
// </view:properties>
|
||||
writer.endElement(
|
||||
NamespaceService.REPOSITORY_VIEW_1_0_URI,
|
||||
"properties",
|
||||
"view:properties");
|
||||
|
||||
// <view:association>
|
||||
writer.startElement(
|
||||
NamespaceService.REPOSITORY_VIEW_1_0_URI,
|
||||
"associations",
|
||||
"view:associations",
|
||||
new AttributesImpl());
|
||||
|
||||
// Output the association details
|
||||
new OutputChildren().doWork(reader, writer);
|
||||
|
||||
// </view:association>
|
||||
writer.endElement(
|
||||
NamespaceService.REPOSITORY_VIEW_1_0_URI,
|
||||
"associations",
|
||||
"view:associations");
|
||||
|
||||
// </act:compositeaction>
|
||||
writer.endElement(
|
||||
ActionModel.TYPE_COMPOSITE_ACTION.getNamespaceURI(),
|
||||
ActionModel.TYPE_COMPOSITE_ACTION.getLocalName(),
|
||||
ActionModel.ACTION_MODEL_PREFIX+ ":" + ActionModel.TYPE_COMPOSITE_ACTION.getLocalName());
|
||||
|
||||
// </rule:action>
|
||||
writer.endElement(
|
||||
RuleModel.ASSOC_ACTION.getNamespaceURI(),
|
||||
RuleModel.ASSOC_ACTION.getLocalName(),
|
||||
RuleModel.RULE_MODEL_PREFIX + ":" + RuleModel.ASSOC_ACTION.getLocalName());
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Output anything else that might be hanging araound
|
||||
ImportFileUpdater.this.outputCurrentElement(reader, writer, new OutputChildren());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// End the rules element
|
||||
writer.endElement(namespace, name, prefix+":"+name);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length == 2)
|
||||
{
|
||||
ImportFileUpdater util = new ImportFileUpdater();
|
||||
util.updateImportFile(args[0], args[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.out.println(" ImportFileUpdater <destination> <source>");
|
||||
System.out.println(" source - 1.3 import file name to be updated");
|
||||
System.out.println(" destination - name of the generated 1.4 import file");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user