diff --git a/config/alfresco/core-services-context.xml b/config/alfresco/core-services-context.xml
index 111a847270..dfedf88af4 100644
--- a/config/alfresco/core-services-context.xml
+++ b/config/alfresco/core-services-context.xml
@@ -241,6 +241,9 @@
false
+
+ ${db.txn.isolation}
+
diff --git a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql b/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql
index e4078a6fdf..dcc69b3183 100644
--- a/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql
+++ b/config/alfresco/dbscripts/create/2.2/org.hibernate.dialect.Dialect/AlfrescoPostCreate-2.2-MappedFKIndexes.sql
@@ -28,8 +28,6 @@ CREATE INDEX fk_alf_autha_ali ON alf_authority_alias (alias_id);
CREATE INDEX fk_alf_autha_aut ON alf_authority_alias (auth_id);
CREATE INDEX fk_alf_cass_pnode ON alf_child_assoc (parent_node_id);
-CREATE INDEX fk_alf_cass_tqn ON alf_child_assoc (type_qname_id);
-CREATE INDEX fk_alf_cass_qnns ON alf_child_assoc (qname_ns_id);
CREATE INDEX fk_alf_cass_cnode ON alf_child_assoc (child_node_id);
-- alf_global_attributes.attribute is declared unique. Indexes may automatically have been created.
@@ -42,20 +40,16 @@ CREATE INDEX fk_alf_matt_matt ON alf_map_attribute_entries (map_id);
CREATE INDEX fk_alf_matt_att ON alf_map_attribute_entries (attribute_id);
CREATE INDEX fk_alf_node_acl ON alf_node (acl_id);
-CREATE INDEX fk_alf_node_tqn ON alf_node (type_qname_id);
CREATE INDEX fk_alf_node_txn ON alf_node (transaction_id);
CREATE INDEX fk_alf_node_store ON alf_node (store_id);
CREATE INDEX fk_alf_nasp_n ON alf_node_aspects (node_id);
CREATE INDEX fk_alf_nass_snode ON alf_node_assoc (source_node_id);
-CREATE INDEX fk_alf_nass_tqn ON alf_node_assoc (type_qname_id);
CREATE INDEX fk_alf_nass_tnode ON alf_node_assoc (target_node_id);
CREATE INDEX fk_alf_nprop_n ON alf_node_properties (node_id);
-CREATE INDEX fk_alf_perm_tqn ON alf_permission (type_qname_id);
-
CREATE INDEX fk_alf_qname_ns ON alf_qname (ns_id);
CREATE INDEX fk_alf_store_root ON alf_store (root_node_id);
@@ -80,7 +74,6 @@ CREATE INDEX fk_avm_nprop_n ON avm_node_properties (node_id);
CREATE INDEX fk_avm_n_acl ON avm_nodes (acl_id);
CREATE INDEX fk_avm_n_store ON avm_nodes (store_new_id);
-CREATE INDEX fk_avm_sprop_qname ON avm_store_properties (qname_id);
CREATE INDEX fk_avm_sprop_store ON avm_store_properties (avm_store_id);
CREATE INDEX fk_avm_s_acl ON avm_stores (acl_id);
diff --git a/config/alfresco/domain/transaction.properties b/config/alfresco/domain/transaction.properties
index a4fe290b7b..7caefb41f3 100644
--- a/config/alfresco/domain/transaction.properties
+++ b/config/alfresco/domain/transaction.properties
@@ -8,7 +8,7 @@ server.transaction.mode.readOnly=PROPAGATION_REQUIRED, readOnly
server.transaction.mode.default=PROPAGATION_REQUIRED
server.transaction.allow-writes=true
-server.transaction.max-retries=20
+server.transaction.max-retries=40
server.transaction.min-retry-wait-ms=100
server.transaction.max-retry-wait-ms=2000
server.transaction.wait-increment-ms=100
\ No newline at end of file
diff --git a/config/alfresco/extension/custom-repository.properties.sample b/config/alfresco/extension/custom-repository.properties.sample
index 4108ca4e86..6e055eca46 100644
--- a/config/alfresco/extension/custom-repository.properties.sample
+++ b/config/alfresco/extension/custom-repository.properties.sample
@@ -52,6 +52,7 @@
#
#db.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#db.url=jdbc:sqlserver://localhost:1433;databaseName=alfresco
+#db.txn.isolation=4096
# The well known RMI registry port is defined in the alfresco-shared.properties file
# alfresco.rmi.services.port=50500
diff --git a/config/alfresco/repository.properties b/config/alfresco/repository.properties
index ce8d943146..ac613a56fe 100644
--- a/config/alfresco/repository.properties
+++ b/config/alfresco/repository.properties
@@ -160,7 +160,8 @@ db.url=jdbc:mysql:///${db.name}
db.username=alfresco
db.password=alfresco
db.pool.initial=10
-db.pool.max=20
+db.pool.max=40
+db.txn.isolation=-1
# Email configuration
mail.host=
diff --git a/source/java/org/alfresco/repo/activities/feed/AbstractFeedGenerator.java b/source/java/org/alfresco/repo/activities/feed/AbstractFeedGenerator.java
index 8fa28170d7..2b13e1b502 100644
--- a/source/java/org/alfresco/repo/activities/feed/AbstractFeedGenerator.java
+++ b/source/java/org/alfresco/repo/activities/feed/AbstractFeedGenerator.java
@@ -52,7 +52,7 @@ public abstract class AbstractFeedGenerator implements FeedGenerator
private RepoCtx ctx = null;
- private boolean busy;
+ private volatile boolean busy;
public void setPostDaoService(ActivityPostDaoService postDaoService)
{
@@ -124,15 +124,13 @@ public abstract class AbstractFeedGenerator implements FeedGenerator
return;
}
- checkProperties();
+ busy = true;
try
{
- // run at least one job cycle
- boolean moreWork = true;
- while (moreWork)
- {
- moreWork = generate();
- }
+ checkProperties();
+
+ // run one job cycle
+ generate();
}
catch (Throwable e)
{
diff --git a/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java b/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java
index 8673ce5579..d191026e2a 100644
--- a/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java
+++ b/source/java/org/alfresco/repo/activities/feed/FeedTaskProcessor.java
@@ -38,12 +38,14 @@ import java.net.URISyntaxException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.TreeMap;
import org.alfresco.repo.activities.feed.control.FeedControlDAO;
import org.alfresco.repo.activities.post.ActivityPostDAO;
@@ -106,6 +108,10 @@ public abstract class FeedTaskProcessor
Configuration cfg = getFreemarkerConfiguration(ctx);
Map> activityTemplates = new HashMap>(10);
+
+ Map> siteConnectedUsers = new TreeMap>();
+
+ Map templateCache = new TreeMap();
// for each activity post ...
for (ActivityPostDAO activityPost : activityPosts)
@@ -192,28 +198,37 @@ public abstract class FeedTaskProcessor
model.put("xmldate", new ISO8601DateFormatMethod());
model.put("repoEndPoint", ctx.getRepoEndPoint());
- Set connectedUsers = null;
- if ((activityPost.getSiteNetwork() == null) || (activityPost.getSiteNetwork().length() == 0))
+ // Get the members of this site
+ String thisSite = activityPost.getSiteNetwork();
+
+ // Save hammering the repository by reusing cached site members
+ Set connectedUsers = siteConnectedUsers.get(thisSite);
+ if (connectedUsers == null)
{
- connectedUsers = new HashSet(1);
- }
- else
- {
- try
+ if ((thisSite == null) || (thisSite.length() == 0))
{
- // Repository callback to get site members
- connectedUsers = getSiteMembers(ctx, activityPost.getSiteNetwork());
+ connectedUsers = Collections.singleton(""); // add empty posting userid - to represent site feed !
}
- catch(Exception e)
+ else
{
- logger.error(">>> Skipping activity post " + activityPost.getId() + " since failed to get site members: " + e);
- updatePostStatus(activityPost.getId(), ActivityPostDAO.STATUS.ERROR);
- continue;
+ try
+ {
+ // Repository callback to get site members
+ connectedUsers = getSiteMembers(ctx, thisSite);
+ connectedUsers.add(""); // add empty posting userid - to represent site feed !
+
+ // Cache them for future use in this same invocation
+ siteConnectedUsers.put(thisSite, connectedUsers);
+ }
+ catch(Exception e)
+ {
+ logger.error(">>> Skipping activity post " + activityPost.getId() + " since failed to get site members: " + e);
+ updatePostStatus(activityPost.getId(), ActivityPostDAO.STATUS.ERROR);
+ continue;
+ }
}
}
-
- connectedUsers.add(""); // add empty posting userid - to represent site feed !
-
+
try
{
startTransaction();
@@ -272,12 +287,12 @@ public abstract class FeedTaskProcessor
model.put("activityData", activityPost.getActivityData());
}
- String activitySummary = processFreemarker(fmTemplate, cfg, model);
+ String activitySummary = processFreemarker(templateCache, fmTemplate, cfg, model);
if (! activitySummary.equals(""))
{
feed.setActivitySummary(activitySummary);
feed.setActivitySummaryFormat(formatFound);
- feed.setSiteNetwork(activityPost.getSiteNetwork());
+ feed.setSiteNetwork(thisSite);
feed.setAppTool(activityPost.getAppTool());
feed.setPostDate(activityPost.getPostDate());
feed.setPostId(activityPost.getId());
@@ -502,9 +517,15 @@ public abstract class FeedTaskProcessor
return cfg;
}
- protected String processFreemarker(String fmTemplate, Configuration cfg, Map model) throws IOException, TemplateException, Exception
+ protected String processFreemarker(Map templateCache, String fmTemplate, Configuration cfg, Map model) throws IOException, TemplateException, Exception
{
- Template myTemplate = cfg.getTemplate(fmTemplate);
+ // Save on lots of modification date checking by caching templates locally
+ Template myTemplate = templateCache.get(fmTemplate);
+ if (myTemplate == null)
+ {
+ myTemplate = cfg.getTemplate(fmTemplate);
+ templateCache.put(fmTemplate, myTemplate);
+ }
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Writer out = new OutputStreamWriter(bos);
diff --git a/source/java/org/alfresco/repo/domain/hibernate/HibernateSessionHelperTest.java b/source/java/org/alfresco/repo/domain/hibernate/HibernateSessionHelperTest.java
index 99cd47df51..cc978379b0 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/HibernateSessionHelperTest.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/HibernateSessionHelperTest.java
@@ -5,6 +5,7 @@ import java.util.Date;
import java.util.Set;
import org.alfresco.model.ContentModel;
+import org.alfresco.repo.domain.AuditableProperties;
import org.alfresco.repo.domain.Node;
import org.alfresco.repo.domain.QNameDAO;
import org.alfresco.repo.domain.Server;
@@ -549,7 +550,9 @@ public class HibernateSessionHelperTest extends BaseSpringTest
node.setTypeQNameId(typeQNameId);
node.setTransaction(transaction);
node.setDeleted(false);
- node.getAuditableProperties().setAuditValues("system", new Date(), false);
+ AuditableProperties ap = new AuditableProperties();
+ node.setAuditableProperties(ap);
+ ap.setAuditValues("system", new Date(), false);
getSession().save(node);
return node;
diff --git a/source/java/org/alfresco/repo/domain/hibernate/NodeImpl.java b/source/java/org/alfresco/repo/domain/hibernate/NodeImpl.java
index 2ec723b4fd..ded2d244b9 100644
--- a/source/java/org/alfresco/repo/domain/hibernate/NodeImpl.java
+++ b/source/java/org/alfresco/repo/domain/hibernate/NodeImpl.java
@@ -82,7 +82,8 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
aspects = new HashSet(5);
properties = new HashMap(5);
- auditableProperties = new AuditableProperties();
+ // Note auditableProperties starts null, as hibernate maps a component containing nulls to null and this would
+ // cause a lot of dirty checks to fail!
}
/**
@@ -355,6 +356,6 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
public void setAuditableProperties(AuditableProperties auditableProperties)
{
- this.auditableProperties = (auditableProperties == null ? new AuditableProperties() : auditableProperties);
+ this.auditableProperties = auditableProperties;
}
}
diff --git a/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java b/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java
index 847c6aa62c..878747b3cf 100644
--- a/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java
+++ b/source/java/org/alfresco/repo/jscript/RhinoScriptProcessor.java
@@ -57,6 +57,8 @@ import org.mozilla.javascript.ImporterTopLevel;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.WrapFactory;
+import org.mozilla.javascript.WrappedException;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.FileCopyUtils;
/**
@@ -64,7 +66,7 @@ import org.springframework.util.FileCopyUtils;
*
* @author Kevin Roast
*/
-public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcessor, ScriptResourceLoader
+public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcessor, ScriptResourceLoader, InitializingBean
{
private static final Log logger = LogFactory.getLog(RhinoScriptProcessor.class);
@@ -82,6 +84,12 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
/** Store root path to resolve cm:name based scripts path from */
private String storePath;
+ /** Pre initialized secure scope object. */
+ private Scriptable secureScope;
+
+ /** Pre initialized non secure scope object. */
+ private Scriptable nonSecureScope;
+
/**
* Set the default store reference
*
@@ -340,27 +348,12 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
Context cx = Context.enter();
try
{
- // The easiest way to embed Rhino is just to create a new scope this way whenever
- // you need one. However, initStandardObjects is an expensive method to call and it
- // allocates a fair amount of memory.
+ // Create a thread-specific scope from one of the shared scopes. See http://www.mozilla.org/rhino/scopes.html
cx.setWrapFactory(wrapFactory);
- Scriptable scope;
- if (!secure)
- {
- scope = cx.initStandardObjects();
- // remove security issue related objects - this ensures the script may not access
- // unsecure java.* libraries or import any other classes for direct access - only
- // the configured root host objects will be available to the script writer
- scope.delete("Packages");
- scope.delete("getClass");
- scope.delete("java");
- }
- else
- {
- // allow access to all libraries and objects, including the importer
- // @see http://www.mozilla.org/rhino/ScriptingJava.html
- scope = new ImporterTopLevel(cx);
- }
+ Scriptable sharedScope = secure ? this.nonSecureScope : this.secureScope;
+ Scriptable scope = cx.newObject(sharedScope);
+ scope.setPrototype(sharedScope);
+ scope.setParentScope(null);
// there's always a model, if only to hold the util objects
if (model == null)
@@ -398,6 +391,15 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
// extract java object result if wrapped by Rhino
return valueConverter.convertValueForRepo((Serializable)result);
}
+ catch (WrappedException w)
+ {
+ Throwable err = w.getWrappedException();
+ if (err instanceof RuntimeException)
+ {
+ throw (RuntimeException) err;
+ }
+ throw new AlfrescoRuntimeException(err.getMessage(), err);
+ }
catch (Throwable err)
{
throw new AlfrescoRuntimeException(err.getMessage(), err);
@@ -464,4 +466,50 @@ public class RhinoScriptProcessor extends BaseProcessor implements ScriptProcess
return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
}
}
+
+
+ /**
+ * Pre initializes two scope objects (one secure and one not) with the standard objects preinitialised. This saves
+ * on very expensive calls to reinitialize a new scope on every web script execution. See
+ * http://www.mozilla.org/rhino/scopes.html
+ *
+ * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+ */
+ public void afterPropertiesSet() throws Exception
+ {
+ // Initialise the secure scope
+ Context cx = Context.enter();
+ try
+ {
+ cx.setWrapFactory(wrapFactory);
+ this.secureScope = cx.initStandardObjects();
+
+ // remove security issue related objects - this ensures the script may not access
+ // unsecure java.* libraries or import any other classes for direct access - only
+ // the configured root host objects will be available to the script writer
+ this.secureScope.delete("Packages");
+ this.secureScope.delete("getClass");
+ this.secureScope.delete("java");
+ }
+ finally
+ {
+ Context.exit();
+ }
+
+ // Initialise the non-secure scope
+ cx = Context.enter();
+ try
+ {
+ cx.setWrapFactory(wrapFactory);
+
+ // allow access to all libraries and objects, including the importer
+ // @see http://www.mozilla.org/rhino/ScriptingJava.html
+ this.nonSecureScope = new ImporterTopLevel(cx);
+
+ }
+ finally
+ {
+ Context.exit();
+ }
+ }
}
diff --git a/source/java/org/alfresco/repo/jscript/ScriptNode.java b/source/java/org/alfresco/repo/jscript/ScriptNode.java
index 49451d5550..e075161854 100644
--- a/source/java/org/alfresco/repo/jscript/ScriptNode.java
+++ b/source/java/org/alfresco/repo/jscript/ScriptNode.java
@@ -55,7 +55,6 @@ import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.lock.LockStatus;
-import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.AssociationRef;
@@ -348,10 +347,6 @@ public class ScriptNode implements Serializable, Scopeable
{
this.services.getFileFolderService().rename(this.nodeRef, name);
}
- catch (FileExistsException e)
- {
- throw new AlfrescoRuntimeException("Failed to rename node " + nodeRef + " to " + name, e);
- }
catch (FileNotFoundException e)
{
throw new AlfrescoRuntimeException("Failed to rename node " + nodeRef + " to " + name, e);
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 7b29611b57..2ad9b88ffd 100644
--- a/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java
+++ b/source/java/org/alfresco/repo/node/db/hibernate/HibernateNodeDaoServiceImpl.java
@@ -114,6 +114,7 @@ import org.hibernate.ScrollableResults;
import org.hibernate.Session;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
+import org.hibernate.exception.ConstraintViolationException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
@@ -765,7 +766,8 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
{
String currentUser = getCurrentUser();
Date currentDate = new Date();
- AuditableProperties auditableProperties = node.getAuditableProperties();
+ AuditableProperties auditableProperties = new AuditableProperties();
+ node.setAuditableProperties(auditableProperties);
auditableProperties.setAuditValues(currentUser, currentDate, false);
}
}
@@ -779,6 +781,11 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
String currentUser = getCurrentUser();
Date currentDate = new Date();
AuditableProperties auditableProperties = node.getAuditableProperties();
+ if (auditableProperties == null)
+ {
+ auditableProperties = new AuditableProperties();
+ node.setAuditableProperties(auditableProperties);
+ }
auditableProperties.setAuditValues(currentUser, currentDate, false);
}
}
@@ -792,6 +799,11 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
String currentUser = getCurrentUser();
Date currentDate = new Date();
AuditableProperties auditableProperties = node.getAuditableProperties();
+ if (auditableProperties == null)
+ {
+ auditableProperties = new AuditableProperties();
+ node.setAuditableProperties(auditableProperties);
+ }
auditableProperties.setAuditValues(currentUser, currentDate, false);
}
}
@@ -810,8 +822,8 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
Node node = null;
if (uuid != null)
{
- // Get any existing Node. A node with this UUID may have existed before, but must be marked
- // deleted; otherwise it will be considered live and valid
+ // Get any existing Node. A node with this UUID may have existed before, but must be marked
+ // deleted; otherwise it will be considered live and valid
node = getNodeOrNull(store, uuid);
}
else
@@ -1025,13 +1037,13 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
{
Long nodeTypeQNameId = qnameDAO.getOrCreateQName(nodeTypeQName).getFirst();
if (!nodeTypeQNameId.equals(node.getTypeQNameId()))
- {
+ {
node.setTypeQNameId(nodeTypeQNameId);
- // We will need to record the change
- recordNodeUpdate(node);
- }
+ // We will need to record the change
+ recordNodeUpdate(node);
}
}
+ }
public Serializable getNodeProperty(Long nodeId, QName propertyQName)
{
@@ -1044,7 +1056,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
if (hasNodeAspect(node, ContentModel.ASPECT_AUDITABLE))
{
AuditableProperties auditableProperties = node.getAuditableProperties();
- return auditableProperties.getAuditableProperty(propertyQName);
+ return auditableProperties == null ? null : auditableProperties.getAuditableProperty(propertyQName);
}
else
{
@@ -1082,6 +1094,10 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
if (hasNodeAspect(node, ContentModel.ASPECT_AUDITABLE))
{
AuditableProperties auditableProperties = node.getAuditableProperties();
+ if (auditableProperties == null)
+ {
+ auditableProperties = new AuditableProperties();
+ }
converted.putAll(auditableProperties.getAuditableProperties());
}
@@ -1272,14 +1288,14 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
aspectQNames = new HashSet(aspectQNames);
// Remove sys:referenceable
aspectQNames.remove(ContentModel.ASPECT_REFERENCEABLE);
-
+
// Convert
Set aspectQNameIds = qnameDAO.convertQNamesToIds(aspectQNames, true);
// Add them
Set nodeAspects = node.getAspects();
nodeAspects.addAll(aspectQNameIds);
-
+
// Record change ID
recordNodeUpdate(node);
}
@@ -1300,7 +1316,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
// Remove them
Set nodeAspects = node.getAspects();
nodeAspects.removeAll(aspectQNameIds);
-
+
// Record change ID
recordNodeUpdate(node);
}
@@ -1549,16 +1565,16 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
Long parentNodeId,
Long childNodeId,
boolean isPrimary,
- QName assocTypeQName,
+ final QName assocTypeQName,
QName assocQName,
String newName)
{
- Node parentNode = (Node) getSession().get(NodeImpl.class, parentNodeId);
+ final Node parentNode = (Node) getSession().get(NodeImpl.class, parentNodeId);
Node childNode = (Node) getSession().get(NodeImpl.class, childNodeId);
final Pair childNameUnique = getChildNameUnique(assocTypeQName, newName);
- ChildAssoc assoc = new ChildAssocImpl();
+ final ChildAssoc assoc = new ChildAssocImpl();
assoc.setTypeQName(qnameDAO, assocTypeQName);
assoc.setChildNodeName(childNameUnique.getFirst());
assoc.setChildNodeNameCrc(childNameUnique.getSecond());
@@ -1567,27 +1583,33 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
assoc.setIndex(-1);
// maintain inverse sets
assoc.buildAssociation(parentNode, childNode);
- // persist it
- Long assocId;
- try
+ // Make sure that all changes to the session are persisted so that we know if any
+ // failures are from the constraint or not
+ DirtySessionMethodInterceptor.flushSession(getSession(false));
+ Long assocId = (Long) getHibernateTemplate().execute(new HibernateCallback()
{
- assocId = (Long) getHibernateTemplate().save(assoc);
- }
- catch (Throwable e)
- {
- // There is already an entity
- if (isDebugEnabled)
+ public Object doInHibernate(Session session)
{
- logger.debug(
- "Duplicate child association detected: \n" +
- " Parent Node: " + parentNode.getId() + "\n" +
- " Child Name Used: " + childNameUnique);
+ try
+ {
+ Object result = session.save(assoc);
+ DirtySessionMethodInterceptor.flushSession(session);
+ return result;
+ }
+ catch (ConstraintViolationException e)
+ {
+ // There is already an entity
+ if (isDebugEnabled)
+ {
+ logger.debug("Duplicate child association detected: \n" + " Parent Node: "
+ + parentNode.getId() + "\n" + " Child Name Used: " + childNameUnique, e);
+ }
+ throw new DuplicateChildNodeNameException(parentNode.getNodeRef(), assocTypeQName, childNameUnique
+ .getFirst());
+ }
}
- throw new DuplicateChildNodeNameException(
- parentNode.getNodeRef(),
- assocTypeQName,
- childNameUnique.getFirst());
- }
+ });
+
// Add it to the cache
Set oldParentAssocIds = parentAssocsCache.get(childNode.getId());
if (oldParentAssocIds != null)
@@ -1629,7 +1651,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
return new Pair(assocId, assoc.getChildAssocRef(qnameDAO));
}
- public void setChildNameUnique(final Long childAssocId, String childName)
+ public void setChildNameUnique(final Long childAssocId, final String childName)
{
/*
* Work out if there has been any change in the name
@@ -1648,33 +1670,31 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
childAssoc.setChildNodeName(childNameUnique.getFirst());
childAssoc.setChildNodeNameCrc(childNameUnique.getSecond().longValue());
// Flush again to force a DB constraint here
- DirtySessionMethodInterceptor.flushSession(session, true);
- // Done
- return null;
+ try
+ {
+ DirtySessionMethodInterceptor.flushSession(session, true);
+ // Done
+ return null;
+ }
+ catch (ConstraintViolationException e)
+ {
+ // There is already an entity
+ if (isDebugEnabled)
+ {
+ logger.debug("Duplicate child association detected: \n" + " Parent Node: "
+ + parentNode.getId() + "\n" + " Child Name Used: " + childNameUnique, e);
+ }
+
+ throw new DuplicateChildNodeNameException(parentNode.getNodeRef(), childAssoc
+ .getTypeQName(qnameDAO), childNameUnique.getFirst());
+ }
}
};
+
// Make sure that all changes to the session are persisted so that we know if any
// failures are from the constraint or not
DirtySessionMethodInterceptor.flushSession(getSession(false));
- try
- {
- getHibernateTemplate().execute(callback);
- }
- catch (Throwable e)
- {
- // There is already an entity
- if (isDebugEnabled)
- {
- logger.debug(
- "Duplicate child association detected: \n" +
- " Parent Node: " + parentNode.getId() + "\n" +
- " Child Name Used: " + childNameUnique);
- }
- throw new DuplicateChildNodeNameException(
- parentNode.getNodeRef(),
- childAssoc.getTypeQName(qnameDAO),
- childNameUnique.getFirst());
- }
+ getHibernateTemplate().execute(callback);
// Done
if (isDebugEnabled)
@@ -1685,7 +1705,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
" Child Assoc: " + childAssoc);
}
}
-
+
/**
* Apply the cm:name to the child association. If the child name is null then
* a GUID is generated as a substitute.
@@ -2973,12 +2993,12 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
{
Query query = session
.getNamedQuery(HibernateNodeDaoServiceImpl.QUERY_GET_USERS_WITHOUT_USAGE)
- .setString("storeProtocol", storeRef.getProtocol())
- .setString("storeIdentifier", storeRef.getIdentifier())
+ .setString("storeProtocol", storeRef.getProtocol())
+ .setString("storeIdentifier", storeRef.getIdentifier())
.setParameter("usernamePropQNameID", usernamePropQNamePair.getFirst()) // cm:username
.setParameter("sizeCurrentPropQNameID", sizeCurrentPropQNamePair.getFirst()) // cm:sizeCurrent
.setParameter("personTypeQNameID", personTypeQNamePair.getFirst()) // cm:person
- ;
+ ;
DirtySessionMethodInterceptor.setQueryFlushMode(session, query);
return query.scroll(ScrollMode.FORWARD_ONLY);
}
@@ -3009,7 +3029,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
// Done
}
-
+
public void getUsersWithUsage(
final StoreRef storeRef,
final ObjectArrayQueryCallback resultsCallback)
@@ -3094,7 +3114,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
Map properties = node.getProperties();
for (Map.Entry entry : properties.entrySet())
{
- PropertyMapKey propertyKey = entry.getKey();
+ PropertyMapKey propertyKey = entry.getKey();
Long propertyQNameId = propertyKey.getQnameId();
QName propertyQName = qnameDAO.getQName(propertyQNameId).getSecond();
NodePropertyValue propertyValue = entry.getValue();
@@ -3190,7 +3210,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
}
// Done
}
-
+
/*
* Queries for transactions
*/
diff --git a/source/java/org/alfresco/repo/processor/ScriptServiceImpl.java b/source/java/org/alfresco/repo/processor/ScriptServiceImpl.java
index 344ba2f7a6..33d0559159 100644
--- a/source/java/org/alfresco/repo/processor/ScriptServiceImpl.java
+++ b/source/java/org/alfresco/repo/processor/ScriptServiceImpl.java
@@ -113,6 +113,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = getScriptProcessor(scriptClasspath);
return scriptProcessor.execute(scriptClasspath, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute script '" + scriptClasspath + "': " + err.getMessage(), err);
@@ -140,6 +144,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
return scriptProcessor.execute(scriptClasspath, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute script '" + scriptClasspath + "': " + err.getMessage(), err);
@@ -167,6 +175,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = getScriptProcessor(scriptRef);
return scriptProcessor.execute(scriptRef, contentProp, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute script '" + scriptRef.toString() + "': " + err.getMessage(), err);
@@ -194,6 +206,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
return scriptProcessor.execute(scriptRef, contentProp, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute script '" + scriptRef.toString() + "': " + err.getMessage(), err);
@@ -218,6 +234,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = getScriptProcessor(location.toString());
return scriptProcessor.execute(location, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute script '" + location.toString() + "': " + err.getMessage(), err);
@@ -242,6 +262,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
return scriptProcessor.execute(location, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute script '" + location.toString() + "': " + err.getMessage(), err);
@@ -278,6 +302,10 @@ public class ScriptServiceImpl implements ScriptService
ScriptProcessor scriptProcessor = lookupScriptProcessor(engine);
return scriptProcessor.executeString(script, model);
}
+ catch (ScriptException err)
+ {
+ throw err;
+ }
catch (Throwable err)
{
throw new ScriptException("Failed to execute supplied script: " + err.getMessage(), err);
diff --git a/source/java/org/alfresco/repo/site/script/Site.java b/source/java/org/alfresco/repo/site/script/Site.java
index 9d5fa9a02d..382390c61e 100644
--- a/source/java/org/alfresco/repo/site/script/Site.java
+++ b/source/java/org/alfresco/repo/site/script/Site.java
@@ -69,7 +69,7 @@ public class Site implements Serializable
private ScriptableQNameMap customProperties = null;
/** Services Registry */
- private ServiceRegistry services;
+ private ServiceRegistry serviceRegistry;
/** Site service */
private SiteService siteService;
@@ -87,7 +87,7 @@ public class Site implements Serializable
*/
/*package*/ Site(SiteInfo siteInfo, ServiceRegistry serviceRegistry, SiteService siteService, Scriptable scope)
{
- this.services = serviceRegistry;
+ this.serviceRegistry = serviceRegistry;
this.siteService = siteService;
this.siteInfo = siteInfo;
this.scope = scope;
@@ -186,7 +186,7 @@ public class Site implements Serializable
ScriptNode node = null;
if (this.siteInfo.getNodeRef() != null)
{
- node = new ScriptNode(this.siteInfo.getNodeRef(), this.services, this.scope);
+ node = new ScriptNode(this.siteInfo.getNodeRef(), this.serviceRegistry, this.scope);
}
return node;
@@ -336,19 +336,11 @@ public class Site implements Serializable
public ScriptNode getContainer(String componentId)
{
ScriptNode container = null;
- try
+ NodeRef containerNodeRef = this.siteService.getContainer(getShortName(), componentId);
+ if (containerNodeRef != null)
{
- NodeRef containerNodeRef = this.siteService.getContainer(getShortName(), componentId);
- if (containerNodeRef != null)
- {
- container = new ScriptNode(containerNodeRef, this.services, this.scope);
- }
+ container = new ScriptNode(containerNodeRef, this.serviceRegistry, this.scope);
}
- catch(AlfrescoRuntimeException e)
- {
- // NOTE: not good practice to catch all, but in general we're not throwing exceptions
- // into the script layer
- }
return container;
}
@@ -385,56 +377,48 @@ public class Site implements Serializable
public ScriptNode createContainer(final String componentId, final String folderType, final Object permissions)
{
ScriptNode container = null;
- try
+ NodeRef containerNodeRef = AuthenticationUtil.runAs(new RunAsWork()
{
- NodeRef containerNodeRef = AuthenticationUtil.runAs(new RunAsWork()
+ public NodeRef doWork() throws Exception
{
- public NodeRef doWork() throws Exception
+ // Get the container type
+ QName folderQName = (folderType == null) ? null : QName.createQName(folderType, serviceRegistry.getNamespaceService());
+
+ // Create the container node
+ NodeRef containerNodeRef = Site.this.siteService.createContainer(getShortName(), componentId, folderQName, null);
+
+ // Set any permissions that might have been provided for the container
+ if (permissions != null && permissions instanceof ScriptableObject)
{
- // Get the container type
- QName folderQName = (folderType == null) ? null : QName.createQName(folderType, services.getNamespaceService());
-
- // Create the container node
- NodeRef containerNodeRef = Site.this.siteService.createContainer(getShortName(), componentId, folderQName, null);
-
- // Set any permissions that might have been provided for the container
- if (permissions != null && permissions instanceof ScriptableObject)
+ ScriptableObject scriptable = (ScriptableObject)permissions;
+ Object[] propIds = scriptable.getIds();
+ for (int i = 0; i < propIds.length; i++)
{
- ScriptableObject scriptable = (ScriptableObject)permissions;
- Object[] propIds = scriptable.getIds();
- for (int i = 0; i < propIds.length; i++)
+ // work on each key in turn
+ Object propId = propIds[i];
+
+ // we are only interested in keys that are formed of Strings
+ if (propId instanceof String)
{
- // work on each key in turn
- Object propId = propIds[i];
-
- // we are only interested in keys that are formed of Strings
- if (propId instanceof String)
- {
- // get the value out for the specified key - it must be String
- final String key = (String)propId;
- final Object value = scriptable.get(key, scriptable);
- if (value instanceof String)
- {
- // Set the permission on the container
- Site.this.services.getPermissionService().setPermission(containerNodeRef, key, (String)value, true);
- }
+ // get the value out for the specified key - it must be String
+ final String key = (String)propId;
+ final Object value = scriptable.get(key, scriptable);
+ if (value instanceof String)
+ {
+ // Set the permission on the container
+ Site.this.serviceRegistry.getPermissionService().setPermission(containerNodeRef, key, (String)value, true);
}
}
- }
-
- return containerNodeRef;
- }
- }, AuthenticationUtil.SYSTEM_USER_NAME);
-
- // Create the script node for the container
- container = new ScriptNode(containerNodeRef, this.services, this.scope);
- }
- catch(AlfrescoRuntimeException e)
- {
- // NOTE: not good practice to catch all, but in general we're not throwing exceptions
- // into the script layer
- }
- return container;
+ }
+ }
+
+ return containerNodeRef;
+ }
+ }, AuthenticationUtil.SYSTEM_USER_NAME);
+
+ // Create the script node for the container
+ container = new ScriptNode(containerNodeRef, this.serviceRegistry, this.scope);
+ return container;
}
/**
@@ -445,17 +429,7 @@ public class Site implements Serializable
*/
public boolean hasContainer(String componentId)
{
- boolean hasContainer = false;
- try
- {
- hasContainer = this.siteService.hasContainer(getShortName(), componentId);
- }
- catch(AlfrescoRuntimeException e)
- {
- // NOTE: not good practice to catch all, but in general we're not throwing exceptions
- // into the script layer
- }
- return hasContainer;
+ return this.siteService.hasContainer(getShortName(), componentId);
}
/**
@@ -470,7 +444,7 @@ public class Site implements Serializable
if (permissions != null && permissions instanceof ScriptableObject)
{
// Get the permission service
- final PermissionService permissionService = this.services.getPermissionService();
+ final PermissionService permissionService = this.serviceRegistry.getPermissionService();
if (!permissionService.getInheritParentPermissions(nodeRef))
{
@@ -525,7 +499,7 @@ public class Site implements Serializable
{
final NodeRef nodeRef = node.getNodeRef();
- PermissionService permissionService = services.getPermissionService();
+ PermissionService permissionService = serviceRegistry.getPermissionService();
try
{
// Ensure node isn't inheriting permissions from an ancestor before deleting
@@ -562,8 +536,8 @@ public class Site implements Serializable
if (this.customProperties == null)
{
// create the custom properties map
- ScriptNode siteNode = new ScriptNode(this.siteInfo.getNodeRef(), this.services);
- this.customProperties = new ContentAwareScriptableQNameMap(siteNode, this.services);
+ ScriptNode siteNode = new ScriptNode(this.siteInfo.getNodeRef(), this.serviceRegistry);
+ this.customProperties = new ContentAwareScriptableQNameMap(siteNode, this.serviceRegistry);
Map props = siteInfo.getCustomProperties();
for (QName qname : props.keySet())
@@ -578,7 +552,7 @@ public class Site implements Serializable
// get the type and label information from the dictionary
String title = null;
String type = null;
- PropertyDefinition propDef = this.services.getDictionaryService().getProperty(qname);
+ PropertyDefinition propDef = this.serviceRegistry.getDictionaryService().getProperty(qname);
if (propDef != null)
{
type = propDef.getDataType().getName().toString();