stefan 2003/08/13 10:03:43
Modified: proposals/jcrri/src/org/apache/slide/jcr/core
ObjectClassManagerImpl.java NodeImpl.java
Log:
fixing unresolved dependencies introduced in last commit
Revision Changes Path
1.4 +15 -889
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassManagerImpl.java
Index: ObjectClassManagerImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassManagerImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ObjectClassManagerImpl.java 12 Aug 2003 10:26:05 -0000 1.3
+++ ObjectClassManagerImpl.java 13 Aug 2003 17:03:43 -0000 1.4
@@ -63,15 +63,11 @@
package org.apache.slide.jcr.core;
import org.apache.log4j.Logger;
-import org.apache.slide.jcr.util.Deserializer;
import javax.jcr.*;
-import javax.jcr.version.OnVersionPropertyAction;
-import javax.jcr.version.OnVersionNodeAction;
import javax.jcr.access.AccessDeniedException;
import javax.jcr.objectclass.*;
import java.util.*;
-import java.io.IOException;
/**
* A <code>ObjectClassManagerImpl</code> ...
@@ -83,292 +79,14 @@
class ObjectClassManagerImpl implements ObjectClassManager {
private static Logger log = Logger.getLogger(ObjectClassManagerImpl.class);
- private static final String DEFAULT_OBJECTCLASSES_RESOURCE_PATH =
"org/apache/slide/jcr/objectclasses.xml";
-
- private static final String OBJECTCLASS_ELEMENT_NAME = "objectClass";
- private static final String NAME_ATTRIBUTE = "name";
- private static final String SUPERCLASSES_ATTRIBUTE = "superClasses";
- private static final String PROPERTYDEF_ELEMENT_NAME = "propertyDef";
- private static final String TYPE_ATTRIBUTE = "type";
- private static final String VALUECONSTRAINT_ATTRIBUTE = "valueConstraint";
- private static final String DEFAULTVALUE_ATTRIBUTE = "defaultValue";
- private static final String AUTOCREATE_ATTRIBUTE = "autoCreate";
- private static final String MANDATORY_ATTRIBUTE = "mandatory";
- private static final String READONLY_ATTRIBUTE = "readOnly";
- private static final String ONVERSION_ATTRIBUTE = "onVersion";
- private static final String CHILDNODEDEF_ELEMENT_NAME = "childNodeDef";
- private static final String OBJECTCLASSCONSTRAINT_ATTRIBUTE =
"objectClassConstraint";
- private static final String DEFAULTOBJECTCLASSES_ATTRIBUTE =
"defaultObjectClasses";
-
- private static final String TYPENAME_UNDEFINED = "Undefined";
-
- private static final String OBJECTCLASSES_PATH = "/system/objectclasses";
-
- private final Ticket systemTicket;
-
// cache of pre-build aggregations of object classes
private final TreeMap aggregates;
- private HashMap registeredOCs;
-
- private final boolean initialized;
-
/**
* Package private constructor
*/
- ObjectClassManagerImpl(Ticket systemTicket) {
- this.systemTicket = systemTicket;
+ ObjectClassManagerImpl() {
aggregates = new TreeMap();
- registeredOCs = new HashMap();
- initialized = init();
- }
-
- private boolean init() {
- org.jdom.input.SAXBuilder builder = new org.jdom.input.SAXBuilder();
- org.jdom.Element root = null;
- try {
- org.jdom.Document doc =
builder.build(getClass().getClassLoader().getResourceAsStream(DEFAULT_OBJECTCLASSES_RESOURCE_PATH));
- root = doc.getRootElement();
- } catch (IOException ioe) {
- log.error("error while reading " + DEFAULT_OBJECTCLASSES_RESOURCE_PATH,
ioe);
- return false;
- } catch (org.jdom.JDOMException jde) {
- log.error("error while parsing " + DEFAULT_OBJECTCLASSES_RESOURCE_PATH,
jde);
- return false;
- }
- // read definitions of default (i.e. built-in) objectclasses
- // (proprietary serialized form)
- ArrayList list = new ArrayList();
- Iterator iter = root.getChildren(OBJECTCLASS_ELEMENT_NAME).iterator();
- while (iter.hasNext()) {
- TransientObjectClassDef ocDef = readOC((org.jdom.Element) iter.next());
- if (ocDef != null) {
- list.add(ocDef);
- }
- }
-
- // iterate over definitions until there are no more definitions with
- // unresolved (i.e. unregistered) dependencies or an error occurs;
-
- int count = -1; // number of registered oc's per iteration
- while (list.size() > 0 && count != 0) {
- count = 0;
- Iterator iterator = list.iterator();
- while (iterator.hasNext()) {
- TransientObjectClassDef ocd = (TransientObjectClassDef)
iterator.next();
- // check if definition has unresolved dependencies
- if (registeredOCs.keySet().containsAll(ocd.getDependencies())) {
- try {
- // try to register it
- registerObjectClass(ocd);
- // remove it from list
- iterator.remove();
- // increase count
- count++;
- } catch (RepositoryException e) {
- log.error("failed to register default objectclasses", e);
- return false;
- }
- }
- }
- }
- if (list.size() > 0) {
- StringBuffer msg = new StringBuffer();
- msg.append("the following default objectclasses could not be registered
because of unresolvable dependencies: ");
- Iterator iterator = list.iterator();
- while (iterator.hasNext()) {
- try {
- msg.append(((TransientObjectClassDef)
iterator.next()).getName());
- msg.append(" ");
- } catch (RepositoryException e) {
- // ignore, should never happen
- msg.append("[???] ");
- }
- }
- log.error(msg.toString());
- return false;
- }
-
- // @todo should the definitions of the default objectclasses be persisted t
content?
-
- return true;
- }
-
- private TransientObjectClassDef readOC(org.jdom.Element ocElem) {
- try {
- String ocName = ocElem.getAttributeValue(NAME_ATTRIBUTE);
- TransientObjectClassDef ocDef = new
TransientObjectClassDef(OBJECTCLASSES_PATH + "/" + ocName);
- // name
- ocDef.setName(ocName);
- // superClasses
- String superClasses = ocElem.getAttributeValue(SUPERCLASSES_ATTRIBUTE);
- if (superClasses != null && superClasses.length() > 0) {
- String[] ocs = splitString(superClasses);
- if (ocs.length > 0) {
- ocDef.setSuperclasses(ocs);
- }
- }
-
- // property definitions
- ArrayList list = new ArrayList();
- Iterator iter = ocElem.getChildren(PROPERTYDEF_ELEMENT_NAME).iterator();
- while (iter.hasNext()) {
- org.jdom.Element elem = (org.jdom.Element) iter.next();
- PropertyDef pd = new PropertyDef();
- // name
- String propName = elem.getAttributeValue(NAME_ATTRIBUTE);
- if (propName != null && propName.length() > 0) {
- pd.setName(propName);
- }
- // type
- String typeName = elem.getAttributeValue(TYPE_ATTRIBUTE);
- if (typeName != null && typeName.length() > 0 &&
!typeName.equals(TYPENAME_UNDEFINED)) {
- try {
- pd.setType(PropertyType.valueFromName(typeName));
- } catch (IllegalArgumentException e) {
- log.error("invalid serialized objectclass definition:
invalid type " + typeName);
- return null;
- }
- }
- // valueConstraint
- String valueConstraint =
elem.getAttributeValue(VALUECONSTRAINT_ATTRIBUTE);
- if (valueConstraint != null && valueConstraint.length() > 0) {
- pd.setValueConstraint(valueConstraint);
- }
- // defaultValue
- String defaultValue =
elem.getAttributeValue(DEFAULTVALUE_ATTRIBUTE);
- if (defaultValue != null && defaultValue.length() > 0) {
- try {
- if (typeName == null || typeName.length() == 0) {
- typeName =
PropertyType.nameFromValue(PropertyType.STRING);
- }
- pd.setDefaultValue(Deserializer.readValue(defaultValue,
typeName));
- } catch (RepositoryException e) {
- log.error("invalid serialized objectclass definition:
invalid defaultValue " + defaultValue, e);
- return null;
- }
- }
- // autoCreate
- String autoCreate = elem.getAttributeValue(AUTOCREATE_ATTRIBUTE);
- if (autoCreate != null && autoCreate.length() > 0) {
- pd.setAutoCreate(Boolean.valueOf(autoCreate).booleanValue());
- }
- // mandatory
- String mandatory = elem.getAttributeValue(MANDATORY_ATTRIBUTE);
- if (mandatory != null && mandatory.length() > 0) {
- pd.setMandatory(Boolean.valueOf(mandatory).booleanValue());
- }
- // onVersion
- String onVersion = elem.getAttributeValue(ONVERSION_ATTRIBUTE);
- if (onVersion != null && onVersion.length() > 0) {
- try {
-
pd.setOnVersion(OnVersionPropertyAction.valueFromName(onVersion));
- } catch (IllegalArgumentException e) {
- log.error("invalid serialized objectclass definition:
invalid onVersion " + onVersion);
- return null;
- }
- }
- // readOnly
- String readOnly = elem.getAttributeValue(READONLY_ATTRIBUTE);
- if (readOnly != null && readOnly.length() > 0) {
- pd.setReadOnly(Boolean.valueOf(readOnly).booleanValue());
- }
-
- list.add(pd);
- }
- if (!list.isEmpty()) {
- ocDef.setPropertyDefs((PropertyDef[]) list.toArray(new
PropertyDef[list.size()]));
- }
-
- // child-node definitions
- list.clear();
- iter = ocElem.getChildren(CHILDNODEDEF_ELEMENT_NAME).iterator();
- while (iter.hasNext()) {
- org.jdom.Element elem = (org.jdom.Element) iter.next();
- ChildNodeDef cnd = new ChildNodeDef();
- // name
- String nodeName = elem.getAttributeValue(NAME_ATTRIBUTE);
- if (nodeName != null && nodeName.length() > 0) {
- cnd.setName(nodeName);
- }
- // objectClassConstraint
- String ocConstraint =
ocElem.getAttributeValue(OBJECTCLASSCONSTRAINT_ATTRIBUTE);
- if (ocConstraint != null && ocConstraint.length() > 0) {
- String[] ocs = splitString(ocConstraint);
- if (ocs.length > 0) {
- cnd.setObjectClassConstraint(ocs);
- }
- }
- // defaultObjectClasses
- String defaultOCs =
ocElem.getAttributeValue(DEFAULTOBJECTCLASSES_ATTRIBUTE);
- if (defaultOCs != null && defaultOCs.length() > 0) {
- String[] ocs = splitString(defaultOCs);
- if (ocs.length > 0) {
- cnd.setDefaultObjectClasses(ocs);
- }
- }
- // autoCreate
- String autoCreate = elem.getAttributeValue(AUTOCREATE_ATTRIBUTE);
- if (autoCreate != null && autoCreate.length() > 0) {
- cnd.setAutoCreate(Boolean.valueOf(autoCreate).booleanValue());
- }
- // onVersion
- String onVersion = elem.getAttributeValue(ONVERSION_ATTRIBUTE);
- if (onVersion != null && onVersion.length() > 0) {
- try {
-
cnd.setOnVersion(OnVersionNodeAction.valueFromName(onVersion));
- } catch (IllegalArgumentException e) {
- log.error("invalid serialized objectclass definition:
invalid onVersion " + onVersion);
- return null;
- }
- }
- // readOnly
- String readOnly = elem.getAttributeValue(READONLY_ATTRIBUTE);
- if (readOnly != null && readOnly.length() > 0) {
- cnd.setReadOnly(Boolean.valueOf(readOnly).booleanValue());
- }
-
- list.add(cnd);
- }
- if (!list.isEmpty()) {
- ocDef.setChildNodeDefs((ChildNodeDef[]) list.toArray(new
ChildNodeDef[list.size()]));
- }
-
- return ocDef;
- } catch (RepositoryException e) {
- log.error("failed to read objectclass definition", e);
- return null;
- }
- }
-
- private static String[] splitString(String commaSeparatedList) {
- ArrayList list = new ArrayList();
- String oc;
- int pos = commaSeparatedList.indexOf(',');
- int start = 0;
- while (pos > -1) {
- oc = commaSeparatedList.substring(start, pos).trim();
- if (oc.length() > 0) {
- list.add(oc);
- }
- start = pos + 1;
- pos = commaSeparatedList.indexOf(',', start);
- }
- oc = commaSeparatedList.substring(start).trim();
- if (oc.length() > 0) {
- list.add(oc);
- }
- return (String[]) list.toArray(new String[list.size()]);
- }
-
- /**
- *
- * @param ocName
- * @return
- */
- synchronized EffectiveObjectClass getEffectiveObjectClass(String ocName)
- throws ObjectClassConflictException, NoSuchObjectClassException,
RepositoryException {
- return getEffectiveObjectClass(new String[]{ocName});
}
/**
@@ -377,24 +95,16 @@
* @return
*/
synchronized EffectiveObjectClass getEffectiveObjectClass(String[] ocNames)
- throws ObjectClassConflictException, NoSuchObjectClassException,
RepositoryException {
- // 1. make sure every single objectclass is registered
- for (int i = 0; i < ocNames.length; i++) {
- if (!registeredOCs.containsKey(ocNames[i])) {
- throw new NoSuchObjectClassException(ocNames[i]);
- }
- }
+ throws ConstraintViolationException, NoSuchObjectClassException,
RepositoryException {
+ EffectiveObjectClass result = EffectiveObjectClass.create(this);
WeightedKey key = new WeightedKey(ocNames);
- // 2. check if aggregate has already been build
+ // short-cut for optimization
if (aggregates.containsKey(key)) {
return (EffectiveObjectClass) aggregates.get(key);
}
- // 3. build aggregate
- EffectiveObjectClass result = EffectiveObjectClass.create(this);
-
// build list of 'best' existing sub-aggregates
ArrayList tmpResults = new ArrayList();
while (key.size() > 0) {
@@ -425,13 +135,11 @@
// build aggregate of remaining object classes
String[] remainder = key.toArray();
for (int i = 0; i < remainder.length; i++) {
- EffectiveObjectClass eoc = null;
- eoc = EffectiveObjectClass.create(this, remainder[i]);
- result = result.merge(eoc);
+ result = result.merge(remainder[i]);
// add to result list
tmpResults.add(result);
// store intermediate result
- WeightedKey k = new WeightedKey(remainder[i]);
+ WeightedKey k = new WeightedKey(new String[]{remainder[i]});
aggregates.put(k, result);
}
break;
@@ -448,463 +156,6 @@
return result;
}
- void checkForCircularInheritance(String[] superclasses, Stack inheritanceChain)
- throws InvalidObjectClassDefException, RepositoryException {
- for (int i = 0; i < superclasses.length; i++) {
- String oc = superclasses[i];
- int pos = inheritanceChain.lastIndexOf(oc);
- if (pos >= 0) {
- StringBuffer buf = new StringBuffer();
- for (int j = 0; j < inheritanceChain.size(); j++) {
- if (j == pos) {
- buf.append("--> ");
- }
- buf.append(inheritanceChain.get(j));
- buf.append(" extends ");
- }
- buf.append("--> ");
- buf.append(oc);
- throw new InvalidObjectClassDefException("circular inheritance
detected: " + buf.toString());
- }
-
- try {
- String[] sca = getObjectClass(oc).getDefinition().getSuperclasses();
- if (sca != null && sca.length > 0) {
- // check recursively
- inheritanceChain.push(oc);
- checkForCircularInheritance(sca, inheritanceChain);
- inheritanceChain.pop();
- }
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "unknown superclass: " + oc;
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- } catch (UnregisteredObjectClassException uoce) {
- String reason = "superclass not registered: " + oc;
- log.error(reason, uoce);
- throw new InvalidObjectClassDefException(reason, uoce);
- }
- }
- }
-
- void checkForCircularNodeAutoCreation(EffectiveObjectClass childNodeEOC, Stack
definingParentOCs)
- throws InvalidObjectClassDefException, RepositoryException {
- // check for circularity through default objectclasses of auto-created
child nodes
- // (objectclss 'a' defines auto-created child node with default objectclass
'a')
- String[] childNodeOCs = childNodeEOC.getAllObjectClasses();
- for (int i = 0; i < childNodeOCs.length; i++) {
- String oc = childNodeOCs[i];
- int pos = definingParentOCs.lastIndexOf(oc);
- if (pos >= 0) {
- StringBuffer buf = new StringBuffer();
- for (int j = 0; j < definingParentOCs.size(); j++) {
- if (j == pos) {
- buf.append("--> ");
- }
- buf.append("objectclass ");
- buf.append(definingParentOCs.get(j));
- buf.append(" defines auto-created child node with default ");
- }
- buf.append("--> ");
- buf.append("objectclass ");
- buf.append(oc);
- throw new InvalidObjectClassDefException("circular node
auto-creation detected: " + buf.toString());
- }
- }
-
- EffectiveObjectClass.NodeDef[] nodeDefs =
childNodeEOC.getAutoCreateNodeDefs();
- for (int i = 0; i < nodeDefs.length; i++) {
- String[] doca = nodeDefs[i].getDefaultObjectClasses();
- String definingOC = nodeDefs[i].getDefiningObjectClass();
- try {
- if (doca != null && doca.length > 0) {
- // check recursively
- definingParentOCs.push(definingOC);
- checkForCircularNodeAutoCreation(getEffectiveObjectClass(doca),
definingParentOCs);
- definingParentOCs.pop();
- }
- } catch (NoSuchObjectClassException nsoce) {
- String reason = definingOC + " defines invalid default
objectclasses for child node " + nodeDefs[i].getName();
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- } catch (ObjectClassConflictException occe) {
- String reason = definingOC + " defines invalid default
objectclasses for child node " + nodeDefs[i].getName();
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- }
- }
- }
-
- /**
- * Checks if the specified value satisfies the specific value constraint.
- *
- * Note that this method might 'consume' the value (i.e. further operations
- * on that value instance may throw <code>IllegalStateException</code>s).
- *
- * @param value
- * @param valueConstraint
- * @param type
- * @throws ConstraintViolationException
- * @throws ValueFormatException
- * @throws RepositoryException
- */
- void checkValueContstraint(Value value, String valueConstraint, int type)
- throws ConstraintViolationException, ValueFormatException,
RepositoryException {
- if (valueConstraint == null) {
- // no constraint, nothing to check
- return;
- }
-
- if (type == PropertyType.UNDEFINED) {
- // no type specified
- log.warn("don't know how to interpret value constraint for unspecified
type");
- // use type of value as fallback
- type = value.getType();
- }
-
- // @todo implement checking value constraint
-
- switch (type) {
- case PropertyType.STRING:
- // format: regexp
- break;
-
- case PropertyType.SOFTLINK:
- // format: comma-separated list of objectclass names
- break;
-
- case PropertyType.BOOLEAN:
- // format: 'true' or 'false'
- break;
-
- case PropertyType.BINARY:
- case PropertyType.DATE:
- case PropertyType.LONG:
- case PropertyType.DOUBLE:
- // format: '(<min>, <max>)' or '[<min>, <max>]'
- break;
-
- default:
- throw new IllegalArgumentException("unknown type: " + type);
- }
- }
-
- /**
- * Validates the <code>ObjectClassDef</cdoe> and returns
- * a registered <code>ObjectClass</code> instance.
- * <p>
- * The validation includes the following checks:
- * <ul>
- * <li>Superclasses must exist and be registered</li>
- * <li>Inheritance graph must not be circular</li>
- * <li>Aggregation of superclasses must not result in name conflicts,
- * ambiguities, etc.</li>
- * <li>Definitions of auto-created properties must specify a name</li>
- * <li>Default values in property definitions must satisfy value constrains
- * in the same property child-node definition</li>
- * <li>Definitions of auto-created child-nodes must specify a name</li>
- * <li>Default objectclasses in child-node definitions must exist and be
- * registered</li>
- * <li>The aggregation of the default objectclasses in child-node definitions
- * must not result in name conflicts, ambiguities, etc.</li>
- * <li>Definitions of auto-created child-nodes must not specify default
- * objectclasses which would lead to infinite child node creation
- * (e.g. objectclass 'A' defines auto-created child node with default
- * objectclass 'A' ...)</li>
- * <li>Objectclasses specified as constraints in child-node definitions
- * must exist and be registered</li>
- * <li>The aggregation of the objectclasses specified as constraints in
- * child-node definitions must not result in name conflicts, ambiguities,
- * etc.</li>
- * <li>Default objectclasses in child-node definitions must satisfy
- * objectclass constraints in the same child-node definition</li>
- * </ul>
- * @param ocd the definition of the new objectclass
- * @return a <code>ObjectClass</code> instance
- * @throws InvalidObjectClassDefException
- * @throws ObjectClassExistsException
- * @throws RepositoryException
- */
- ObjectClass registerObjectClass(ObjectClassDef ocd)
- throws InvalidObjectClassDefException, ObjectClassExistsException,
RepositoryException {
- String name = ocd.getName();
- if (name == null || name.length() == 0) {
- throw new InvalidObjectClassDefException("no name specified");
- }
-
- if (registeredOCs.containsKey(name)) {
- throw new ObjectClassExistsException(name);
- }
-
- // validate superclasses
- String[] superclasses = ocd.getSuperclasses();
- for (int i = 0; i < superclasses.length; i++) {
- // simple check for infinite recursion
- // (won't trap recursion on a deeper inheritance level)
- if (name.equals(superclasses[i])) {
- String reason = "invalid superclass: " + superclasses[i] + "
(infinite recursion))";
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- if (!registeredOCs.containsKey(superclasses[i])) {
- String reason = "invalid superclass: " + superclasses[i];
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- }
-
- // check for circularity in inheritance chain ('a' extends 'b' extends 'a'):
- Stack inheritanceChain = new Stack();
- inheritanceChain.push(name);
- checkForCircularInheritance(superclasses, inheritanceChain);
-
- // note that infinite recursion through inheritance is automatically being
checked
- // by the following call to getEffectiveObjectClass
- // as it's impossible to register an objectclass definition which
references a
- // superclass that isn't registered yet...
-
- // build effective (i.e. merged and resolved) objectclass from superclasses
- // and check for conflicts
- if (superclasses.length > 0) {
- try {
- getEffectiveObjectClass(superclasses);
- } catch (ObjectClassConflictException occe) {
- String reason = "failed to validate superclasses";
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "failed to validate superclasses";
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- }
- }
-
- // validate property definitions
- PropertyDef[] pda = ocd.getPropertyDefs();
- for (int i = 0; i < pda.length; i++) {
- PropertyDef pd = pda[i];
- // check that auto-created properties specify a name
- if (pd.getName() == null && pd.isAutoCreate()) {
- String reason = "auto-created properties must specify a name";
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- // check that default value satisfies value constraint
- Value val = pd.getDefaultValue();
- String constraint = pd.getValueConstraint();
- if (val != null && constraint != null && constraint.length() > 0) {
- try {
- checkValueContstraint(val, constraint, pd.getType());
- } catch (ConstraintViolationException cve) {
- String reason = "default value of property " + (pd.getName() ==
null ? "<any>" : pd.getName()) + " does not satisfy value constraint " + constraint;
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- } catch (ValueFormatException vfe) {
- String reason = "in valid default value/value constraint for
property " + (pd.getName() == null ? "<any>" : pd.getName());
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- }
- }
-
- // validate child-node definitions
- ChildNodeDef[] cnda = ocd.getChildNodeDefs();
- for (int i = 0; i < cnda.length; i++) {
- ChildNodeDef cnd = cnda[i];
- // check that auto-created child-nodes specify a name
- if (cnd.getName() == null && cnd.isAutoCreate()) {
- String reason = "auto-created child-nodes must specify a name";
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- // check default objectclasses
- String[] doca = cnd.getDefaultObjectClasses();
- boolean referenceToSelf = false;
- EffectiveObjectClass defaultOCs = null;
- if (doca != null) {
- for (int j = 0; j < doca.length; j++) {
- // check if this objectclass specifies itself as default
objectclass
- if (name.equals(doca[j])) {
- referenceToSelf = true;
- }
- // the default objectclasses must all be registered
- // with one notable exception: the objectclass just being
registered
- if (!name.equals(doca[j]) &&
!registeredOCs.containsKey(doca[j])) {
- String reason = "invalid default objectclass: " + doca[j];
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- }
- // build effective (i.e. merged and resolved) objectclass from
default objectclasses
- // and check for conflicts
- if (doca.length > 0) {
- if (!referenceToSelf) {
- try {
- defaultOCs = getEffectiveObjectClass(doca);
- if (cnd.isAutoCreate()) {
- // check for circularity through default
objectclasses of auto-created child nodes
- // (objectclass 'a' defines auto-created child node
with default objectclass 'a')
- Stack definingOCs = new Stack();
- definingOCs.push(name);
- checkForCircularNodeAutoCreation(defaultOCs,
definingOCs);
- }
- } catch (ObjectClassConflictException occe) {
- String reason = "failed to validate default
objectclasses";
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "failed to validate default
objectclasses";
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- }
- } else {
- // the default objectclasses include at least one reference
to
- // the objectclass just being registered; this calls for
- // special treatment...
-
- // FIXME ugly and clumsy code
-
- ArrayList docl = new ArrayList(doca.length);
- for (int j = 0; j < doca.length; j++) {
- if (!name.equals(doca[j])) {
- docl.add(doca[j]);
- }
- }
- try {
- // we need to buiild the effective objectclass in 2
steps:
- // 1. build effective objectclass from 'this'
objectclass definition
- // 2. build effective objectclass from the remainder
and merge it with 1.
- defaultOCs = EffectiveObjectClass.create(this, ocd);
- if (docl.size() > 0) {
- defaultOCs.merge(getEffectiveObjectClass((String[])
docl.toArray(new String[docl.size()])));
- }
- } catch (ObjectClassConflictException occe) {
- String reason = "failed to validate default
objectclasses";
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "failed to validate default
objectclasses";
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- }
- }
- }
- }
-
- // check objectclass constraints
- String[] occa = cnd.getObjectClassConstraint();
- referenceToSelf = false;
- if (occa != null) {
- for (int j = 0; j < occa.length; j++) {
- // check if this objectclass specifies itself as objectclass
constraint
- if (name.equals(occa[j])) {
- referenceToSelf = true;
- }
- // the objectclasses specified as constraints must all be
registered
- // with one notable exception: the objectclass jsut being
registered
- if (!name.equals(occa[j]) &&
!registeredOCs.containsKey(occa[j])) {
- String reason = "invalid objectclass constraint: " +
occa[j];
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- // check if default objectclasses satisfy the objectclass
constraint
- if (defaultOCs != null &&
!defaultOCs.containsObjectClass(occa[j])) {
- String reason = "default objectclasses do not satisfy
objectclass constraint " + occa[j];
- log.error(reason);
- throw new InvalidObjectClassDefException(reason);
- }
- }
-
- // build effective (i.e. merged and resolved) objectclass from
objectclass constraints
- // and check for conflicts
- if (occa.length > 0) {
- if (!referenceToSelf) {
- try {
- getEffectiveObjectClass(occa);
- } catch (ObjectClassConflictException occe) {
- String reason = "failed to validate objectclass
constraints";
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "failed to validate objectclass
constraints";
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- }
- } else {
- // the objectclass constraints contains at least one
reference
- // to the objectclass just being registered; this calls for
- // special treatment...
-
- // FIXME ugly and clumsy code
-
- ArrayList occl = new ArrayList(occa.length);
- for (int j = 0; j < occa.length; j++) {
- if (!name.equals(occa[j])) {
- occl.add(occa[j]);
- }
- }
- try {
- // we need to buiild the effective objectclass in 2
steps
- // 1. build effective objectclass from 'this'
objectclass definition
- // 2. build effective objectclass from the remainder
and merge it with 1.
- EffectiveObjectClass eoc =
EffectiveObjectClass.create(this, ocd);
- if (occl.size() > 0) {
- eoc.merge(getEffectiveObjectClass((String[])
occl.toArray(new String[occl.size()])));
- }
- } catch (ObjectClassConflictException occe) {
- String reason = "failed to validate objectclass
constraints";
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "failed to validate objectclass
constraints";
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- }
- }
- }
- }
- }
-
- // check for circularity through default objectclasses of auto-created
child nodes
- // (objectclss 'a' defines auto-created child node with default objectclass
'a')
-
- // now build effective (i.e. merged and resolved) objectclass from
- // this objectclass definition; this will potentially detect more
- // conflicts or problems
- EffectiveObjectClass eoc = null;
- try {
- eoc = EffectiveObjectClass.create(this, ocd);
- } catch (ObjectClassConflictException occe) {
- String reason = "failed to resolve objectclass definition";
- log.error(reason, occe);
- throw new InvalidObjectClassDefException(reason, occe);
- } catch (NoSuchObjectClassException nsoce) {
- String reason = "failed to resolve objectclass definition";
- log.error(reason, nsoce);
- throw new InvalidObjectClassDefException(reason, nsoce);
- }
-
- // store new effective objectclass instance
- WeightedKey k = new WeightedKey(name);
- aggregates.put(k, eoc);
-
- // create objectclass instance and 'register' it
- ObjectClassImpl oc = ObjectClassImpl.create(this, ocd);
- registeredOCs.put(name, oc);
- return oc;
- }
-
- void unregisterObjectClass(String name) throws UnregisteredObjectClassException
{
- if (!registeredOCs.containsKey(name)) {
- throw new UnregisteredObjectClassException(name);
- }
- registeredOCs.remove(name);
- // remove effective objectclass from aggregates cache
- aggregates.remove(new WeightedKey(name));
-
- // @todo remove also any objectclasses & aggregates which have dependencies
to this objectclass
- }
-
//---------------------------------------------------< ObjectCLassManager >
/**
* @see ObjectClassManager#createObjectClassDef
@@ -918,17 +169,16 @@
* @see ObjectClassManager#getAllObjectClasses
*/
public ObjectClassIterator getAllObjectClasses() throws RepositoryException {
- return new
IteratorHelper(Collections.unmodifiableCollection(registeredOCs.values()).iterator());
+ // @todo implement getAllObjectClasses
+ return new IteratorHelper(Collections.EMPTY_LIST.iterator());
}
/**
* @see ObjectClassManager#getObjectClass
*/
public ObjectClass getObjectClass(String name) throws
NoSuchObjectClassException {
- if (!registeredOCs.containsKey(name)) {
- throw new NoSuchObjectClassException(name);
- }
- return (ObjectClass) registeredOCs.get(name);
+ // @todo implement getObjectClass
+ return null;
}
/**
@@ -965,22 +215,6 @@
/**
*
- * @param ocName
- */
- WeightedKey(String ocName) {
- this(new String[]{ocName}, 1);
- }
-
- /**
- *
- * @param ocName
- */
- WeightedKey(String ocName, int weight) {
- this(new String[]{ocName}, weight);
- }
-
- /**
- *
* @param ocNames
*/
WeightedKey(String[] ocNames) {
@@ -1084,112 +318,4 @@
return getKey().compareTo(other.getKey());
}
}
-
- //--------------------------------------------------------< inner classes >
- /**
- * <code>TransientObjectClassDef</code> only serves a light-weight in-memory
- * holder of an objectclass definition. The definiton is neither persisted
- * nor is it read from content. This class can be used to circumvent
- * bootstrap (or 'chicken & egg' kind of) problems: objectclasses are
- * 'created' from definitions which are stored in content which relies on
- * objectclasses...).
- * <p>
- * The methods <code>register()</code> and
<code>getRegisteredObjectClass()</code>
- * are not implemented, i.e. they allways return <code>null</code>.
- */
- private class TransientObjectClassDef implements ObjectClassDef {
- String name;
- String definitionPath;
- String[] superClasses;
- ChildNodeDef[] childNodeDefs;
- PropertyDef[] propertyDefs;
-
- Set dependencies;
-
- TransientObjectClassDef(String definitionPath) {
- this.name = "";
- this.definitionPath = definitionPath;
- superClasses = new String[0];
- childNodeDefs = new ChildNodeDef[0];
- propertyDefs = new PropertyDef[0];
- }
-
- Collection getDependencies() {
- if (dependencies == null) {
- dependencies = new HashSet();
- for (int i = 0; i < superClasses.length; i++) {
- dependencies.add(superClasses[i]);
- }
- for (int i = 0; i < childNodeDefs.length; i++) {
- String[] ocNames = childNodeDefs[i].getDefaultObjectClasses();
- if (ocNames != null && ocNames.length > 0) {
- for (int j = 0; j < ocNames.length; j++) {
- dependencies.add(ocNames[j]);
- }
- }
- ocNames = childNodeDefs[i].getObjectClassConstraint();
- if (ocNames != null && ocNames.length > 0) {
- for (int j = 0; j < ocNames.length; j++) {
- dependencies.add(ocNames[j]);
- }
- }
- }
- }
- return dependencies;
- }
-
- void resetDependencies() {
- dependencies = null;
- }
-
- //---------------------------------------------------< ObjectClassDef >
- public ChildNodeDef[] getChildNodeDefs() throws RepositoryException {
- return childNodeDefs;
- }
-
- public String getDefinitionPath() throws RepositoryException {
- return definitionPath;
- }
-
- public String getName() throws RepositoryException {
- return name;
- }
-
- public PropertyDef[] getPropertyDefs() throws RepositoryException {
- return propertyDefs;
- }
-
- public ObjectClass getRegisteredObjectClass() {
- // not implemented
- return null;
- }
-
- public String[] getSuperclasses() throws RepositoryException {
- return superClasses;
- }
-
- public ObjectClass register() throws InvalidObjectClassDefException,
ObjectClassExistsException, RepositoryException {
- // not implemented
- return null;
- }
-
- public void setChildNodeDefs(ChildNodeDef[] defs) throws
ObjectClassRegisteredException, RepositoryException {
- resetDependencies();
- childNodeDefs = defs;
- }
-
- public void setName(String name) throws ObjectClassRegisteredException,
RepositoryException {
- this.name = name;
- }
-
- public void setPropertyDefs(PropertyDef[] defs) throws
ObjectClassRegisteredException, RepositoryException {
- propertyDefs = defs;
- }
-
- public void setSuperclasses(String[] names) throws
ObjectClassRegisteredException, RepositoryException {
- resetDependencies();
- superClasses = names;
- }
- }
-}
-
+}
\ No newline at end of file
1.9 +33 -37
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeImpl.java
Index: NodeImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/NodeImpl.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- NodeImpl.java 12 Aug 2003 10:26:05 -0000 1.8
+++ NodeImpl.java 13 Aug 2003 17:03:43 -0000 1.9
@@ -70,7 +70,6 @@
import javax.jcr.access.Permission;
import javax.jcr.objectclass.NoSuchObjectClassException;
import javax.jcr.objectclass.ObjectClass;
-import javax.jcr.objectclass.ObjectClassConflictException;
import javax.jcr.version.InvalidVersionException;
import javax.jcr.version.InvalidVersionLabelException;
import javax.jcr.version.MergeResolver;
@@ -237,7 +236,6 @@
InvalidPathException,
ConstraintViolationException,
NoSuchObjectClassException,
- ObjectClassConflictException,
RepositoryException {
NodeData data = (NodeData) getElementData();
// check existence
@@ -404,9 +402,9 @@
} catch (IOException ioe) {
log.error("failed to deserialize node(s)", ioe);
throw new InvalidSerializedDataException("failed to deserialize
node(s)", ioe);
- } catch (org.jdom.JDOMException jde) {
- log.error("failed to deserialize node(s)", jde);
- throw new InvalidSerializedDataException("failed to deserialize
node(s)", jde);
+ } catch (org.jdom.JDOMException e) {
+ log.error("failed to deserialize node(s)", e);
+ throw new InvalidSerializedDataException("failed to deserialize
node(s)", e);
} finally {
// result of the bulk operation
try {
@@ -526,7 +524,7 @@
* @see Node#addNode(String, String[])
*/
public Node addNode(String path, String[] objectClasses)
- throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException,
ObjectClassConflictException, AccessDeniedException, RepositoryException {
+ throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException, AccessDeniedException,
RepositoryException {
return addNode(path, objectClasses, false);
}
@@ -534,7 +532,7 @@
* @see Node#addNode(String, String[], boolean)
*/
public Node addNode(String path, String[] objectClasses, boolean adjustName)
- throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException,
ObjectClassConflictException, AccessDeniedException, RepositoryException {
+ throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException, AccessDeniedException,
RepositoryException {
String nodePath;
try {
nodePath = PathUtil.makeCanonicalPath(elementPath, path);
@@ -665,7 +663,7 @@
* @see Node#setProperty(String, String)
*/
public Property setProperty(String name, String value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -675,7 +673,7 @@
* @see Node#setProperty(String, InputStream)
*/
public Property setProperty(String name, InputStream value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -685,7 +683,7 @@
* @see Node#setProperty(String, boolean)
*/
public Property setProperty(String name, boolean value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -695,7 +693,7 @@
* @see Node#setProperty(String, double)
*/
public Property setProperty(String name, double value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -705,7 +703,7 @@
* @see Node#setProperty(String, long)
*/
public Property setProperty(String name, long value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -715,7 +713,7 @@
* @see Node#setProperty(String, Calendar)
*/
public Property setProperty(String name, Calendar value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -725,7 +723,7 @@
* @see Node#setProperties(NameValuePair[])
*/
public PropertyIterator setProperties(NameValuePair[] properties)
- throws InvalidPathException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws InvalidPathException, ConstraintViolationException,
StaleValueException, AccessDeniedException, RepositoryException {
ArrayList modified = new ArrayList();
boolean succeeded = false;
// bulk operation is about to start
@@ -757,7 +755,7 @@
* @see Node#setProperty(String, Value)
*/
public Property setProperty(String name, Value value)
- throws ElementNotFoundException, ConstraintViolationException,
ValueFormatException, StaleValueException, AccessDeniedException, RepositoryException {
+ throws ElementNotFoundException, ValueFormatException,
StaleValueException, AccessDeniedException, RepositoryException {
Property prop = getProperty(name);
prop.setValue(value);
return prop;
@@ -1194,8 +1192,8 @@
*/
public PropertyIterator addProperties(NameValuePair[] properties)
throws ElementExistsException, InvalidPathException,
- ConstraintViolationException, ValueFormatException,
- AccessDeniedException, RepositoryException {
+ ConstraintViolationException, AccessDeniedException,
+ RepositoryException {
ArrayList newProperties = new ArrayList();
boolean succeeded = false;
// bulk operation is about to start
@@ -1304,7 +1302,7 @@
* @see Node#addNode(String, boolean, NameValuePair[])
*/
public Node addNode(String path, boolean adjustName, NameValuePair[] properties)
- throws ElementExistsException, InvalidPathException,
ConstraintViolationException, AccessDeniedException, RepositoryException {
+ throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException, AccessDeniedException,
RepositoryException {
Node newNode = addNode(path, adjustName);
newNode.addProperties(properties);
return newNode;
@@ -1314,7 +1312,7 @@
* @see Node#addNode(String, String[], boolean, NameValuePair[])
*/
public Node addNode(String path, String[] objectClasses, boolean adjustName,
NameValuePair[] properties)
- throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException,
ObjectClassConflictException, AccessDeniedException, RepositoryException {
+ throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException, AccessDeniedException,
RepositoryException {
// @todo implement objectclass support
log.warn("ignoring objectClasses argument");
return addNode(path, adjustName, properties);
@@ -1324,7 +1322,7 @@
* @see Node#addNode(String, String[], NameValuePair[])
*/
public Node addNode(String path, String[] objectClasses, NameValuePair[]
properties)
- throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException,
ObjectClassConflictException, AccessDeniedException, RepositoryException {
+ throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException, AccessDeniedException,
RepositoryException {
return addNode(path, objectClasses, false, properties);
}
@@ -1332,26 +1330,16 @@
* @see Node#addNode(String, NameValuePair[])
*/
public Node addNode(String path, NameValuePair[] properties)
- throws ElementExistsException, InvalidPathException,
ConstraintViolationException, AccessDeniedException, RepositoryException {
+ throws ElementExistsException, InvalidPathException,
ConstraintViolationException, NoSuchObjectClassException, AccessDeniedException,
RepositoryException {
return addNode(path, false, properties);
}
/**
* @see Node#addObjectClass
*/
- public void addObjectClass(String objectClassName)
- throws UnsupportedRepositoryOperationException,
NoSuchObjectClassException, ConstraintViolationException,
ObjectClassConflictException, AccessDeniedException, RepositoryException {
+ public void addObjectClass(String objectClassName) throws
NoSuchObjectClassException, ConstraintViolationException {
// @todo implement objectclass support
- throw new UnsupportedRepositoryOperationException();
- }
-
- /**
- * @see Node#removeObjectClass
- */
- public void removeObjectClass(String objectClassName)
- throws UnsupportedRepositoryOperationException,
NoSuchObjectClassException, ConstraintViolationException, AccessDeniedException,
RepositoryException {
- // @todo implement objectclass support
- throw new UnsupportedRepositoryOperationException();
+ log.warn("ignoring call to addObjectClass(String)");
}
/**
@@ -1538,6 +1526,14 @@
throws InvalidPathException, AccessDeniedException,
ConstraintViolationException, RepositoryException {
// @todo handle version nodes and hardlonks
elemMgr.removeElement(element.getPath());
+ }
+
+ /**
+ * @see Node#removeObjectClass
+ */
+ public void removeObjectClass(String objectClassName) throws
NoSuchObjectClassException, ConstraintViolationException {
+ // @todo implement objectclass support
+ log.warn("ignoring call to removeObjectClass(String)");
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]