Merged V3.0 to HEAD

12185: Fix 3.0 SP1 installation on non-Oracle databases. Removed creation of indexes in AlfrescoPostCreate-2.2-MappedFKIndexes.sql that were also in AlfrescoPostCreate-2.2-Extra.sql
  12186: Performance improvements to HibernateNodeDaoServiceImpl
  12188: Multi user tests: enable graceful web script recovery on optimistic locking failure (...)
  12191: Improve Javascript execution performance in Web Scripts & Improve error presentation (...) thrown by JavaScript
  12192: Share performance improvements: stop AbstractFeedGenerator from 'choking' the repository with too many web script requests
  12193: Multi user testing: don't suppress all exceptions during Wiki Move.
  12194: Multi user testing. Don't suppress all runtime exceptions in script site node object.
  12195: Multi user testing. Convert User bean object to use a retrying transaction so that optimistic locking failures are handled.
  12196: Multi user testing: Configuration changes to support concurrent access by 20 users


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12522 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2008-12-19 17:44:01 +00:00
parent de05f999e4
commit 08676ac665
14 changed files with 287 additions and 201 deletions

View File

@@ -241,6 +241,9 @@
<property name="defaultAutoCommit" >
<value>false</value>
</property>
<property name="defaultTransactionIsolation" >
<value>${db.txn.isolation}</value>
</property>
</bean>
<!-- Characterset decoder -->

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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=

View File

@@ -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)
{

View File

@@ -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<String, List<String>> activityTemplates = new HashMap<String, List<String>>(10);
Map<String, Set<String>> siteConnectedUsers = new TreeMap<String, Set<String>>();
Map<String, Template> templateCache = new TreeMap<String, Template>();
// 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<String> 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<String> connectedUsers = siteConnectedUsers.get(thisSite);
if (connectedUsers == null)
{
connectedUsers = new HashSet<String>(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<String, Object> model) throws IOException, TemplateException, Exception
protected String processFreemarker(Map<String, Template> templateCache, String fmTemplate, Configuration cfg, Map<String, Object> 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);

View File

@@ -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;

View File

@@ -82,7 +82,8 @@ public class NodeImpl extends LifecycleAdapter implements Node, Serializable
aspects = new HashSet<Long>(5);
properties = new HashMap<PropertyMapKey, NodePropertyValue>(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;
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);

View File

@@ -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<QName>(aspectQNames);
// Remove sys:referenceable
aspectQNames.remove(ContentModel.ASPECT_REFERENCEABLE);
// Convert
Set<Long> aspectQNameIds = qnameDAO.convertQNamesToIds(aspectQNames, true);
// Add them
Set<Long> nodeAspects = node.getAspects();
nodeAspects.addAll(aspectQNameIds);
// Record change ID
recordNodeUpdate(node);
}
@@ -1300,7 +1316,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
// Remove them
Set<Long> 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<String, Long> 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<Long> oldParentAssocIds = parentAssocsCache.get(childNode.getId());
if (oldParentAssocIds != null)
@@ -1629,7 +1651,7 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
return new Pair<Long, ChildAssociationRef>(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 <b>cm:name</b> to the child association. If the child name is <tt>null</tt> 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<PropertyMapKey, NodePropertyValue> properties = node.getProperties();
for (Map.Entry<PropertyMapKey, NodePropertyValue> 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
*/

View File

@@ -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);

View File

@@ -69,7 +69,7 @@ public class Site implements Serializable
private ScriptableQNameMap<String, CustomProperty> 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>()
{
NodeRef containerNodeRef = AuthenticationUtil.runAs(new RunAsWork<NodeRef>()
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<String, CustomProperty>(siteNode, this.services);
ScriptNode siteNode = new ScriptNode(this.siteInfo.getNodeRef(), this.serviceRegistry);
this.customProperties = new ContentAwareScriptableQNameMap<String, CustomProperty>(siteNode, this.serviceRegistry);
Map<QName, Serializable> 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();