mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-16 17:55:15 +00:00
Merged V2.0 to HEAD
5457: Merge error on copy web project action 5459: AR-1278 5461: 5462: A few deployment fixes 5469: Dictionary messages 5470: L2 cache checks 5478: WCM-374 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5485 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
parent
138d1780cb
commit
0570c77f46
@ -5,8 +5,8 @@ d_dictionary.model.err.type_not_found=Failed to create anonymous type as specifi
|
||||
d_dictionary.model.err.aspect_not_found=Failed to create anonymous type as specified aspect {0} not found
|
||||
|
||||
d_dictionary.constraint.err.cyclic_ref=Constraint ''{0}'' is part of a cyclic reference of constraints
|
||||
d_dictionary.constraint.err.type_and_ref=Constraint ''{0}'' cannot have a ''type'' and be a ''reference'' attribute
|
||||
d_dictionary.constraint.err.type_or_ref=Constraint ''{0}'' cannot have a ''type'' and be a ''reference'' attribute
|
||||
d_dictionary.constraint.err.type_and_ref=Constraint ''{0}'' cannot have a 'type' and be a 'reference' attribute
|
||||
d_dictionary.constraint.err.type_or_ref=Constraint ''{0}'' cannot have a 'type' and be a 'reference' attribute
|
||||
d_dictionary.constraint.err.ref_not_found=Constraint reference ''{0}'' not found on constraint ''{1}''
|
||||
d_dictionary.constraint.err.anon_needs_property=Anonymous constraints can only be declared within the context of a property
|
||||
d_dictionary.constraint.err.invalid_type=Constraint type ''{0}'' on constraint ''{1}'' is not a well-known type or a valid Constraint implementation
|
||||
@ -26,16 +26,22 @@ d_dictionary.property.err.cannot_relax_mandatory_enforcement=Cannot relax mandat
|
||||
d_dictionary.constraint.regex.no_match=Value ''{0}'' does not match regular expression: {1}
|
||||
d_dictionary.constraint.regex.match=Value ''{0}'' matches regular expression: {1}
|
||||
|
||||
d_dictionary.constraint.numeric_range.invalid_min_value=Invalid ''minValue'' property: {0}
|
||||
d_dictionary.constraint.numeric_range.invalid_max_value=Invalid ''maxValue'' property: {0}
|
||||
d_dictionary.constraint.numeric_range.invalid_min_value=Invalid 'minValue' property: {0}
|
||||
d_dictionary.constraint.numeric_range.invalid_max_value=Invalid 'maxValue' property: {0}
|
||||
d_dictionary.constraint.numeric_range.non_numeric=Property value could not be converted to a double: {0}
|
||||
d_dictionary.constraint.numeric_range.out_of_range=Numeric value ''{0}'' is not in range [{1}; {2}]
|
||||
|
||||
d_dictionary.constraint.string_length.invalid_min_length=Invalid ''minLength'' property: {0}
|
||||
d_dictionary.constraint.string_length.invalid_max_length=Invalid ''maxLength'' property: {0}
|
||||
d_dictionary.constraint.string_length.invalid_min_length=Invalid 'minLength' property: {0}
|
||||
d_dictionary.constraint.string_length.invalid_max_length=Invalid 'maxLength' property: {0}
|
||||
d_dictionary.constraint.string_length.non_string=Property value could not be converted to a String: {0}
|
||||
d_dictionary.constraint.string_length.invalid_length=String length of ''{0}'' is not in range [{1}; {2}]
|
||||
|
||||
d_dictionary.constraint.list_of_values.no_values=The list of allowed values is empty
|
||||
d_dictionary.constraint.list_of_values.non_string=Property value could not be converted to a String: {0}
|
||||
d_dictionary.constraint.list_of_values.invalid_value=The value is not an allowed value: {0}
|
||||
|
||||
d_dictionary.constraint.user_name.invalid_user_name=The value ''{0}'' is not an allowed user name: it is an authority of type: {1}
|
||||
d_dictionary.constraint.user_name.non_string=Property value could not be converted to a String: {0}
|
||||
|
||||
d_dictionary.constraint.authority_name.invalid_authority_name=The value ''{0}'' is not an allowed authority name: it is an authority of type: {1}
|
||||
d_dictionary.constraint.authority_name.non_string=Property value could not be converted to a String: {0}
|
@ -137,7 +137,10 @@ patch.userAndPersonUserNamesAsIdentifiers.result=Reindexed user:user and cm:pers
|
||||
patch.contentFormFolderType.description=Update WCM Content Form folder type.
|
||||
patch.contentFormFolderType.result=Updated {0} WCM Content Form objects to 'wcm:formfolder' type.
|
||||
|
||||
patch.webscripts.description=Adds Web Scripts to Data Dictionary.
|
||||
|
||||
patch.groupNamesAsIdentifiers.description=Reindex usr:authorityContainer gids as identifiers
|
||||
patch.groupNamesAsIdentifiers.result=Reindex usr:authorityContainer gids as identifiers
|
||||
patch.groupNamesAsIdentifiers.result=Reindex usr:authorityContainer gids as identifiers
|
||||
|
||||
patch.invalidUserPersonAndGroup.description=Fix up invalid uids for people and users; and invalid gids for groups
|
||||
patch.invalidUserPersonAndGroup.result=Fixed ''{0}'' invalid user nodes, ''{1}'' invalid person nodes and ''{2}'' invalid authority nodes.
|
||||
|
||||
patch.webscripts.description=Adds Web Scripts to Data Dictionary.
|
||||
|
@ -19,6 +19,7 @@
|
||||
<parameter name="expression"><value><![CDATA[(.*[\"\*\\\>\<\?\/\:\|\xA3\xAC\%\&\+\;]+.*)|(.*[\.]?.*[\.]+$)|(.*[ ]+$)]]></value></parameter>
|
||||
<parameter name="requiresMatch"><value>false</value></parameter>
|
||||
</constraint>
|
||||
<constraint name="cm:userNameConstraint" type="org.alfresco.repo.dictionary.constraint.UserNameConstraint" />
|
||||
</constraints>
|
||||
|
||||
<types>
|
||||
@ -147,6 +148,9 @@
|
||||
<property name="cm:userName">
|
||||
<type>d:text</type>
|
||||
<mandatory>true</mandatory>
|
||||
<constraints>
|
||||
<constraint ref="cm:userNameConstraint" />
|
||||
</constraints>
|
||||
</property>
|
||||
<property name="cm:homeFolder">
|
||||
<type>d:noderef</type>
|
||||
|
@ -684,6 +684,24 @@
|
||||
<ref bean="indexerAndSearcherFactory" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="patch.invalidUserPersonAndGroup" class="org.alfresco.repo.admin.patch.impl.InvalidUserPersonAndGroupPatch" parent="basePatch" >
|
||||
<property name="id"><value>patch.invalidUserPersonAndGroup</value></property>
|
||||
<property name="description"><value>patch.invalidUserPersonAndGroup.description</value></property>
|
||||
<property name="fixesFromSchema"><value>0</value></property>
|
||||
<property name="fixesToSchema"><value>39</value></property>
|
||||
<property name="targetSchema"><value>40</value></property>
|
||||
<!-- bootstrap view -->
|
||||
<property name="userImporterBootstrap">
|
||||
<ref bean="userBootstrap" />
|
||||
</property>
|
||||
<property name="spacesImporterBootstrap">
|
||||
<ref bean="spacesBootstrap" />
|
||||
</property>
|
||||
<property name="dictionaryService">
|
||||
<ref bean="dictionaryService" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="patch.webscripts" class="org.alfresco.repo.admin.patch.impl.GenericBootstrapPatch" parent="basePatch" >
|
||||
<property name="id"><value>patch.webscripts</value></property>
|
||||
|
@ -1,112 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ehcache>
|
||||
<diskStore path="java.io.tmpdir"/>
|
||||
<cacheManagerEventListenerFactory class="" properties=""/>
|
||||
<defaultCache
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
timeToIdleSeconds="120"
|
||||
timeToLiveSeconds="120"
|
||||
overflowToDisk="false"
|
||||
diskPersistent="false"
|
||||
diskExpiryThreadIntervalSeconds="120"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.alfresco.repo.avm.AVMNodeImpl"
|
||||
maxElementsInMemory="5000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.alfresco.repo.avm.FileContentImpl"
|
||||
maxElementsInMemory="5000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.alfresco.repo.avm.RepositoryImpl"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.alfresco.repo.avm.VersionRootImpl"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.alfresco.repo.avm.ChildEntryImpl"
|
||||
maxElementsInMemory="5000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="ChildEntry.ByNameParent"
|
||||
maxElementsInMemory="5000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="ChildEntry.ByParent"
|
||||
maxElementsInMemory="500"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="ChildEntry.ByParentChild"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.alfresco.repo.avm.DeletedChildImpl"
|
||||
maxElementsInMemory="2000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="DeletedChild.ByParent"
|
||||
maxElementsInMemory="1000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="Property.Lookup"
|
||||
maxElementsInMemory="5000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="Properties.Lookup"
|
||||
maxElementsInMemory="2000"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.hibernate.cache.UpdateTimestampsCache"
|
||||
maxElementsInMemory="500"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
<cache name="org.hibernate.cache.StandardQueryCache"
|
||||
maxElementsInMemory="500"
|
||||
eternal="true"
|
||||
overflowToDisk="false"
|
||||
timeToIdleSeconds="300"
|
||||
timeToLiveSeconds="600"
|
||||
memoryStoreEvictionPolicy="LRU"/>
|
||||
</ehcache>
|
@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
|
||||
<hibernate-configuration>
|
||||
<session-factory>
|
||||
<!--
|
||||
<property name="connection.username">britt</property>
|
||||
<property name="connection.password"></property>
|
||||
<property name="connection.url">jdbc:postgresql://127.0.0.1/avm</property>
|
||||
<property name="connection.driver_class">org.postgresql.Driver</property>
|
||||
-->
|
||||
<property name="connection.username">root</property>
|
||||
<property name="connection.password"></property>
|
||||
<property name="connection.url">jdbc:mysql://127.0.0.1/avm</property>
|
||||
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
|
||||
<property name="current_session_context_class">thread</property>
|
||||
<property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
|
||||
<!-- <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property> -->
|
||||
<property name="show_sql">false</property>
|
||||
<property name="order_updates">false</property>
|
||||
<property name="connection.isolation">2</property>
|
||||
<!--
|
||||
<property name="connection.connection_provider">org.sciencething.cpool.ConnectionProvider</property>
|
||||
<property name="cpool.size">20</property>
|
||||
-->
|
||||
|
||||
<property name="c3p0.min_size">4</property>
|
||||
<property name="c3p0.max_size">32</property>
|
||||
<property name="c3p0.timeout">60</property>
|
||||
<property name="c3p0.max_statements">0</property>
|
||||
<property name="c3p0.idle_test_period">60</property>
|
||||
|
||||
<property name="default_batch_fetch_size">16</property>
|
||||
<property name="jdbc.batch_versioned_data">true</property>
|
||||
<property name="jdbc.batch_size">15</property>
|
||||
<property name="cach.use_second_level_cache">true</property>
|
||||
<property name="cache.use_query_cache">true</property>
|
||||
<mapping resource="org/alfresco/repo/avm/hibernate/AVM.hbm.xml"/>
|
||||
</session-factory>
|
||||
</hibernate-configuration>
|
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing
|
||||
*/
|
||||
|
||||
package org.alfresco.repo.admin.patch.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.admin.patch.AbstractPatch;
|
||||
import org.alfresco.repo.importer.ImporterBootstrap;
|
||||
import org.alfresco.service.cmr.dictionary.ClassDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintException;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.ResultSetRow;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
|
||||
/**
|
||||
* Patch usr:user and cm:person objects so that the user name properties are in the index in untokenized form. If not authentication may fail in mixed language use.
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public class InvalidUserPersonAndGroupPatch extends AbstractPatch
|
||||
{
|
||||
private static final String MSG_SUCCESS = "patch.invalidUserPersonAndGroup.result";
|
||||
|
||||
private ImporterBootstrap spacesImporterBootstrap;
|
||||
|
||||
private ImporterBootstrap userImporterBootstrap;
|
||||
|
||||
private DictionaryService dictionaryService;
|
||||
|
||||
public InvalidUserPersonAndGroupPatch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void setSpacesImporterBootstrap(ImporterBootstrap spacesImporterBootstrap)
|
||||
{
|
||||
this.spacesImporterBootstrap = spacesImporterBootstrap;
|
||||
}
|
||||
|
||||
public void setUserImporterBootstrap(ImporterBootstrap userImporterBootstrap)
|
||||
{
|
||||
this.userImporterBootstrap = userImporterBootstrap;
|
||||
}
|
||||
|
||||
public void setDictionaryService(DictionaryService dictionaryService)
|
||||
{
|
||||
this.dictionaryService = dictionaryService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String applyInternal() throws Exception
|
||||
{
|
||||
int users = deleteInvalid(ContentModel.PROP_USER_USERNAME, userImporterBootstrap.getStoreRef(), "USER_");
|
||||
int people = deleteInvalid(ContentModel.PROP_USERNAME, spacesImporterBootstrap.getStoreRef(), "USER_");
|
||||
int authorities = deleteInvalid(ContentModel.PROP_AUTHORITY_NAME, userImporterBootstrap.getStoreRef(), "GROUP_");
|
||||
return I18NUtil.getMessage(MSG_SUCCESS, users, people, authorities);
|
||||
}
|
||||
|
||||
private int deleteInvalid(QName property, StoreRef store, String prefix)
|
||||
{
|
||||
PropertyDefinition propDef = dictionaryService.getProperty(property);
|
||||
if (propDef == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ClassDefinition typeDef = propDef.getContainerClass();
|
||||
|
||||
String query;
|
||||
if (typeDef.isAspect())
|
||||
{
|
||||
query = "ASPECT:\"" + typeDef.getName() + "\"";
|
||||
}
|
||||
else
|
||||
{
|
||||
query = "TYPE:\"" + typeDef.getName() + "\"";
|
||||
}
|
||||
|
||||
List<ConstraintDefinition> conDefs = propDef.getConstraints();
|
||||
|
||||
SearchParameters sp = new SearchParameters();
|
||||
sp.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
sp.setQuery(query);
|
||||
sp.addStore(store);
|
||||
ResultSet rs = null;
|
||||
int invalidCount = 0;
|
||||
try
|
||||
{
|
||||
rs = searchService.query(sp);
|
||||
for (ResultSetRow row : rs)
|
||||
{
|
||||
NodeRef nodeRef = row.getNodeRef();
|
||||
boolean valid = true;
|
||||
Serializable value = nodeService.getProperty(nodeRef, property);
|
||||
String checkValue = null;
|
||||
try
|
||||
{
|
||||
checkValue = DefaultTypeConverter.INSTANCE.convert(String.class, value);
|
||||
}
|
||||
catch (TypeConversionException e)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ConstraintDefinition con : conDefs)
|
||||
{
|
||||
try
|
||||
{
|
||||
con.getConstraint().evaluate(value);
|
||||
}
|
||||
catch (ConstraintException e)
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if(!valid)
|
||||
{
|
||||
nodeService.setProperty(nodeRef, property, prefix+checkValue);
|
||||
invalidCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (rs != null)
|
||||
{
|
||||
rs.close();
|
||||
}
|
||||
}
|
||||
return invalidCount;
|
||||
}
|
||||
}
|
@ -195,19 +195,21 @@ public class AVMDeploySnapshotAction extends ActionExecuterAbstractBase
|
||||
DeploymentReport report = null;
|
||||
try
|
||||
{
|
||||
String host = targetServer;
|
||||
int port = defaultRmiPort;
|
||||
|
||||
// check whether there is a port number present, if so, use it
|
||||
int idx = targetServer.indexOf(":");
|
||||
if (idx != -1)
|
||||
{
|
||||
host = targetServer.substring(0, idx);
|
||||
String strPort = targetServer.substring(idx+1);
|
||||
port = Integer.parseInt(strPort);
|
||||
}
|
||||
|
||||
// TODO: we need to capture username/password for the remote server at some
|
||||
// point, for now we use the admin/admin account, need to externalise this too!
|
||||
report = this.deployService.deployDifference(version, path, targetServer, port,
|
||||
// point, for now we use the configured username/password for all servers
|
||||
report = this.deployService.deployDifference(version, path, host, port,
|
||||
remoteUsername, remotePassword, targetPath, true, false, false, callback);
|
||||
}
|
||||
catch (Throwable err)
|
||||
@ -247,8 +249,7 @@ public class AVMDeploySnapshotAction extends ActionExecuterAbstractBase
|
||||
}
|
||||
|
||||
// create the deployment report node
|
||||
createDeploymentReportNode(report, (String)action.getParameterValue(PARAM_TARGET_SERVER),
|
||||
version, websiteRef, startDate, deployError);
|
||||
createDeploymentReportNode(report, targetServer, version, websiteRef, startDate, deployError);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,40 +46,48 @@ import org.springframework.beans.PropertyAccessException;
|
||||
*
|
||||
* @author Derek Hulley
|
||||
*/
|
||||
/*package*/ class M2ConstraintDefinition implements ConstraintDefinition
|
||||
/* package */class M2ConstraintDefinition implements ConstraintDefinition
|
||||
{
|
||||
public static final String ERR_CYCLIC_REF = "d_dictionary.constraint.err.cyclic_ref";
|
||||
|
||||
public static final String ERR_TYPE_AND_REF = "d_dictionary.constraint.err.type_and_ref";
|
||||
|
||||
public static final String ERR_TYPE_OR_REF = "d_dictionary.constraint.err.type_or_ref";
|
||||
|
||||
public static final String ERR_REF_NOT_FOUND = "d_dictionary.constraint.err.ref_not_found";
|
||||
|
||||
public static final String ERR_ANON_NEEDS_PROPERTY = "d_dictionary.constraint.err.anon_needs_property";
|
||||
|
||||
public static final String ERR_INVALID_TYPE = "d_dictionary.constraint.err.invalid_type";
|
||||
|
||||
public static final String ERR_SIMPLE_AND_LIST = "d_dictionary.constraint.err.property_simple_and_list";
|
||||
|
||||
public static final String ERR_CONSTRUCT_FAILURE = "d_dictionary.constraint.err.construct_failure";
|
||||
|
||||
public static final String ERR_PROPERTY_MISMATCH = "d_dictionary.constraint.err.property_mismatch";
|
||||
|
||||
private static int anonPropCount = 0;
|
||||
|
||||
|
||||
private ModelDefinition model;
|
||||
|
||||
private NamespacePrefixResolver prefixResolver;
|
||||
|
||||
private M2Constraint m2Constraint;
|
||||
|
||||
private QName name;
|
||||
|
||||
private Constraint constraint;
|
||||
|
||||
private boolean resolving;
|
||||
|
||||
/*package*/ M2ConstraintDefinition(
|
||||
M2PropertyDefinition m2PropertyDef,
|
||||
M2Constraint m2Constraint,
|
||||
|
||||
/* package */M2ConstraintDefinition(M2PropertyDefinition m2PropertyDef, M2Constraint m2Constraint,
|
||||
NamespacePrefixResolver prefixResolver)
|
||||
{
|
||||
this(m2PropertyDef.getModel(), m2PropertyDef, m2Constraint, prefixResolver);
|
||||
}
|
||||
|
||||
/*package*/ M2ConstraintDefinition(
|
||||
ModelDefinition modelDefinition,
|
||||
M2PropertyDefinition m2PropertyDef,
|
||||
M2Constraint m2Constraint,
|
||||
NamespacePrefixResolver prefixResolver)
|
||||
|
||||
/* package */M2ConstraintDefinition(ModelDefinition modelDefinition, M2PropertyDefinition m2PropertyDef,
|
||||
M2Constraint m2Constraint, NamespacePrefixResolver prefixResolver)
|
||||
{
|
||||
this.model = modelDefinition;
|
||||
this.m2Constraint = m2Constraint;
|
||||
@ -103,8 +111,8 @@ import org.springframework.beans.PropertyAccessException;
|
||||
this.name = QName.createQName(m2Constraint.getName(), prefixResolver);
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ synchronized void resolveDependencies(ModelQuery query)
|
||||
|
||||
/* package */synchronized void resolveDependencies(ModelQuery query)
|
||||
{
|
||||
if (resolving)
|
||||
{
|
||||
@ -121,7 +129,7 @@ import org.springframework.beans.PropertyAccessException;
|
||||
resolving = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void resolveInternal(ModelQuery query)
|
||||
{
|
||||
if (constraint != null)
|
||||
@ -187,39 +195,43 @@ import org.springframework.beans.PropertyAccessException;
|
||||
// property setters
|
||||
BeanWrapper beanWrapper = new BeanWrapperImpl(constraint);
|
||||
List<M2NamedValue> constraintNamedValues = m2Constraint.getParameters();
|
||||
for (M2NamedValue namedValue : constraintNamedValues)
|
||||
|
||||
if (constraintNamedValues != null)
|
||||
{
|
||||
Object value = null;
|
||||
if (namedValue.getSimpleValue() != null && namedValue.getListValue() != null)
|
||||
for (M2NamedValue namedValue : constraintNamedValues)
|
||||
{
|
||||
throw new DictionaryException(ERR_SIMPLE_AND_LIST, shortName, namedValue.getName());
|
||||
}
|
||||
else if (namedValue.getSimpleValue() != null)
|
||||
{
|
||||
value = namedValue.getSimpleValue();
|
||||
}
|
||||
else if (namedValue.getListValue() != null)
|
||||
{
|
||||
value = namedValue.getListValue();
|
||||
}
|
||||
try
|
||||
{
|
||||
beanWrapper.setPropertyValue(namedValue.getName(), value);
|
||||
}
|
||||
catch (PropertyAccessException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValue.getName(), shortName);
|
||||
}
|
||||
catch (InvalidPropertyException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValue.getName(), shortName);
|
||||
Object value = null;
|
||||
if (namedValue.getSimpleValue() != null && namedValue.getListValue() != null)
|
||||
{
|
||||
throw new DictionaryException(ERR_SIMPLE_AND_LIST, shortName, namedValue.getName());
|
||||
}
|
||||
else if (namedValue.getSimpleValue() != null)
|
||||
{
|
||||
value = namedValue.getSimpleValue();
|
||||
}
|
||||
else if (namedValue.getListValue() != null)
|
||||
{
|
||||
value = namedValue.getListValue();
|
||||
}
|
||||
try
|
||||
{
|
||||
beanWrapper.setPropertyValue(namedValue.getName(), value);
|
||||
}
|
||||
catch (PropertyAccessException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValue.getName(), shortName);
|
||||
}
|
||||
catch (InvalidPropertyException e)
|
||||
{
|
||||
throw new DictionaryException(ERR_PROPERTY_MISMATCH, e, namedValue.getName(), shortName);
|
||||
}
|
||||
}
|
||||
}
|
||||
// now initialize
|
||||
constraint.initialize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #getName()
|
||||
*/
|
||||
@ -228,7 +240,7 @@ import org.springframework.beans.PropertyAccessException;
|
||||
{
|
||||
return getName().toString();
|
||||
}
|
||||
|
||||
|
||||
public ModelDefinition getModel()
|
||||
{
|
||||
return model;
|
||||
@ -243,7 +255,7 @@ import org.springframework.beans.PropertyAccessException;
|
||||
{
|
||||
return constraint;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Well-known constraint types
|
||||
*/
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing
|
||||
*/
|
||||
package org.alfresco.repo.dictionary.constraint;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintException;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
|
||||
public class AuthorityNameConstraint extends AbstractConstraint
|
||||
{
|
||||
|
||||
private static final String ERR_INVALID_AUTHORITY_NAME = "d_dictionary.constraint.authority_name.invalid_authority_name";
|
||||
private static final String ERR_NON_STRING = "d_dictionary.constraint.authority_name.non_string";
|
||||
|
||||
@Override
|
||||
protected void evaluateSingleValue(Object value)
|
||||
{
|
||||
// ensure that the value can be converted to a String
|
||||
String checkValue = null;
|
||||
try
|
||||
{
|
||||
checkValue = DefaultTypeConverter.INSTANCE.convert(String.class, value);
|
||||
}
|
||||
catch (TypeConversionException e)
|
||||
{
|
||||
throw new ConstraintException(ERR_NON_STRING, value);
|
||||
}
|
||||
|
||||
AuthorityType type = AuthorityType.getAuthorityType(checkValue);
|
||||
if((type != AuthorityType.GROUP) && (type != AuthorityType.ROLE))
|
||||
{
|
||||
throw new ConstraintException(ERR_INVALID_AUTHORITY_NAME, value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing
|
||||
*/
|
||||
package org.alfresco.repo.dictionary.constraint;
|
||||
|
||||
import org.alfresco.service.cmr.dictionary.ConstraintException;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
|
||||
/**
|
||||
* Apply constraints for user names.
|
||||
*
|
||||
* @author andyh
|
||||
*
|
||||
*/
|
||||
public class UserNameConstraint extends AbstractConstraint
|
||||
{
|
||||
private static final String ERR_INVALID_USERNAME = "d_dictionary.constraint.user_name.invalid_user_name";
|
||||
private static final String ERR_NON_STRING = "d_dictionary.constraint.user_name.non_string";
|
||||
|
||||
@Override
|
||||
protected void evaluateSingleValue(Object value)
|
||||
{
|
||||
// ensure that the value can be converted to a String
|
||||
String checkValue = null;
|
||||
try
|
||||
{
|
||||
checkValue = DefaultTypeConverter.INSTANCE.convert(String.class, value);
|
||||
}
|
||||
catch (TypeConversionException e)
|
||||
{
|
||||
throw new ConstraintException(ERR_NON_STRING, value);
|
||||
}
|
||||
|
||||
AuthorityType type = AuthorityType.getAuthorityType(checkValue);
|
||||
if((type != AuthorityType.USER) && (type != AuthorityType.GUEST))
|
||||
{
|
||||
throw new ConstraintException(ERR_INVALID_USERNAME, value, type);
|
||||
}
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -314,8 +314,15 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
// create the node instance
|
||||
Node childNode = nodeDaoService.newNode(store, newId, nodeTypeQName);
|
||||
|
||||
// get the parent node
|
||||
// Get the parent node
|
||||
Node parentNode = getNodeNotNull(parentRef);
|
||||
// Create the association
|
||||
ChildAssoc childAssoc = nodeDaoService.newChildAssoc(
|
||||
parentNode,
|
||||
childNode,
|
||||
true,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
|
||||
// Set the default property values
|
||||
addDefaultPropertyValues(nodeTypeDef, properties);
|
||||
@ -331,13 +338,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
propertiesAfter = setPropertiesImpl(childNode, properties);
|
||||
}
|
||||
|
||||
// create the association
|
||||
ChildAssoc childAssoc = nodeDaoService.newChildAssoc(
|
||||
parentNode,
|
||||
childNode,
|
||||
true,
|
||||
assocTypeQName,
|
||||
assocQName);
|
||||
// Ensure child uniqueness
|
||||
setChildUniqueName(childNode); // ensure uniqueness
|
||||
ChildAssociationRef childAssocRef = childAssoc.getChildAssocRef();
|
||||
|
||||
@ -1069,7 +1070,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
Node node = getNodeNotNull(nodeRef);
|
||||
// get the assocs pointing to it
|
||||
Collection<ChildAssoc> parentAssocs = node.getParentAssocs();
|
||||
Collection<ChildAssoc> parentAssocs = nodeDaoService.getParentAssocs(node);
|
||||
// list of results
|
||||
Collection<NodeRef> results = new ArrayList<NodeRef>(parentAssocs.size());
|
||||
for (ChildAssoc assoc : parentAssocs)
|
||||
@ -1089,7 +1090,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
Node node = getNodeNotNull(nodeRef);
|
||||
// get the assocs pointing to it
|
||||
Collection<ChildAssoc> parentAssocs = node.getParentAssocs();
|
||||
Collection<ChildAssoc> parentAssocs = nodeDaoService.getParentAssocs(node);
|
||||
// shortcut if there are no assocs
|
||||
if (parentAssocs.size() == 0)
|
||||
{
|
||||
@ -1319,7 +1320,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
{
|
||||
NodeRef currentNodeRef = currentNode.getNodeRef();
|
||||
// get the parent associations of the given node
|
||||
Collection<ChildAssoc> parentAssocs = currentNode.getParentAssocs();
|
||||
Collection<ChildAssoc> parentAssocs = nodeDaoService.getParentAssocs(currentNode);
|
||||
// does the node have parents
|
||||
boolean hasParents = parentAssocs.size() > 0;
|
||||
// does the current node have a root aspect?
|
||||
@ -1651,7 +1652,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
}
|
||||
// parent associations
|
||||
ArrayList<ChildAssociationRef> archivedParentAssocRefs = new ArrayList<ChildAssociationRef>(5);
|
||||
for (ChildAssoc assoc : node.getParentAssocs())
|
||||
for (ChildAssoc assoc : nodeDaoService.getParentAssocs(node))
|
||||
{
|
||||
Long relatedNodeId = assoc.getParent().getId();
|
||||
if (nodeStatusesById.containsKey(relatedNodeId))
|
||||
@ -1952,7 +1953,7 @@ public class DbNodeServiceImpl extends AbstractNodeServiceImpl
|
||||
useName = (String) nameValue.getValue(DataTypeDefinition.TEXT);
|
||||
}
|
||||
// get all the parent assocs
|
||||
Collection<ChildAssoc> parentAssocs = childNode.getParentAssocs();
|
||||
Collection<ChildAssoc> parentAssocs = nodeDaoService.getParentAssocs(childNode);
|
||||
for (ChildAssoc assoc : parentAssocs)
|
||||
{
|
||||
QName assocTypeQName = assoc.getTypeQName();
|
||||
|
@ -223,6 +223,13 @@ public interface NodeDaoService
|
||||
*/
|
||||
public ChildAssoc getPrimaryParentAssoc(Node node);
|
||||
|
||||
/**
|
||||
* Get all parent associations for the node. This methods includes a cache safety check.
|
||||
* @param node the child node
|
||||
* @return Returns all parent associations for the node.
|
||||
*/
|
||||
public Collection<ChildAssoc> getParentAssocs(Node node);
|
||||
|
||||
/**
|
||||
* @return Returns the persisted and filled association
|
||||
* @see NodeAssoc
|
||||
|
@ -900,6 +900,49 @@ public class HibernateNodeDaoServiceImpl extends HibernateDaoSupport implements
|
||||
getSession().flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* This method includes a check to ensure that the <b>parentAssocs</b> cache
|
||||
* isn't incorrectly empty.
|
||||
*/
|
||||
public Collection<ChildAssoc> getParentAssocs(Node node)
|
||||
{
|
||||
Collection<ChildAssoc> parentAssocs = node.getParentAssocs();
|
||||
if (parentAssocs.size() == 0)
|
||||
{
|
||||
// the only condition where this is allowed is if the given node is a root node
|
||||
Store store = node.getStore();
|
||||
Node rootNode = store.getRootNode();
|
||||
if (rootNode == null)
|
||||
{
|
||||
// a store without a root node - the entire store is hosed
|
||||
throw new DataIntegrityViolationException("Store has no root node: \n" +
|
||||
" store: " + store);
|
||||
}
|
||||
if (!rootNode.equals(node))
|
||||
{
|
||||
// Reload the node to ensure that it is properly initialized
|
||||
getSession().refresh(node);
|
||||
// Check if it has any parents yet.
|
||||
if (node.getParentAssocs().size() == 0)
|
||||
{
|
||||
// It wasn't the root node and definitely has no parent
|
||||
throw new DataIntegrityViolationException(
|
||||
"Non-root node has no primary parent: \n" +
|
||||
" child: " + node);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Repeat this method with confidence
|
||||
return getParentAssocs(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Done
|
||||
return parentAssocs;
|
||||
}
|
||||
|
||||
private Set<NodeRef> warnedDuplicateParents = new HashSet<NodeRef>(3);
|
||||
/**
|
||||
* @inheritDoc
|
||||
|
@ -68,7 +68,7 @@ public abstract class AbstractReindexComponent implements IndexRecovery
|
||||
private static Log logger = LogFactory.getLog(AbstractReindexComponent.class);
|
||||
|
||||
/** kept to notify the thread that it should quit */
|
||||
private static VmShutdownListener vmShutdownListener = new VmShutdownListener("MissingContentReindexComponent");
|
||||
private static VmShutdownListener vmShutdownListener = new VmShutdownListener("IndexRecovery");
|
||||
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
/** provides transactions to atomically index each missed transaction */
|
||||
|
@ -14,6 +14,10 @@
|
||||
<namespace uri="http://www.alfresco.org/model/user/1.0" prefix="usr"/>
|
||||
</namespaces>
|
||||
|
||||
<constraints>
|
||||
<constraint name="usr:userNameConstraint" type="org.alfresco.repo.dictionary.constraint.UserNameConstraint" />
|
||||
<constraint name="usr:authorityNameConstraint" type="org.alfresco.repo.dictionary.constraint.AuthorityNameConstraint" />
|
||||
</constraints>
|
||||
|
||||
<types>
|
||||
|
||||
@ -30,6 +34,9 @@
|
||||
<!-- This is so you can not break person lookup -->
|
||||
<property name="usr:username">
|
||||
<type>d:text</type>
|
||||
<constraints>
|
||||
<constraint ref="usr:userNameConstraint" />
|
||||
</constraints>
|
||||
</property>
|
||||
<property name="usr:password">
|
||||
<type>d:text</type>
|
||||
@ -66,6 +73,9 @@
|
||||
<!-- This is so you can not break group lookup -->
|
||||
<property name="usr:authorityName">
|
||||
<type>d:text</type>
|
||||
<constraints>
|
||||
<constraint ref="usr:authorityNameConstraint" />
|
||||
</constraints>
|
||||
</property>
|
||||
<property name="usr:members">
|
||||
<type>d:text</type>
|
||||
|
Loading…
x
Reference in New Issue
Block a user