stefan 2003/06/06 10:28:24
Modified: proposals/jcrri/src/org/apache/slide/jcr/core
ContentNode.java EffectiveObjectClass.java
ElementImpl.java ElementListener.java
ElementManager.java ElementManagerSupport.java
HierarchyNode.java IteratorHelper.java
NodeImpl.java PropertyImpl.java
RepositoryFactory.java RepositoryImpl.java
RootContentNode.java TicketImpl.java
Added: proposals/jcrri/src/org/apache/slide/jcr/core
ObjectClassDefImpl.java ObjectClassImpl.java
ObjectClassManagerImpl.java
Removed: proposals/jcrri/src/org/apache/slide/jcr/core
AutoCreatedNode.java ObjectClassManagerEx.java
Log:
jcr ri: objectclasses (work in progress)
Revision Changes Path
1.5 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ContentNode.java
Index: ContentNode.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ContentNode.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
1.2 +361 -24
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/EffectiveObjectClass.java
Index: EffectiveObjectClass.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/EffectiveObjectClass.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- EffectiveObjectClass.java 30 May 2003 13:22:36 -0000 1.1
+++ EffectiveObjectClass.java 6 Jun 2003 17:28:23 -0000 1.2
@@ -64,58 +64,395 @@
import org.apache.log4j.Logger;
-import javax.jcr.objectclass.ObjectClass;
import javax.jcr.ConstraintViolationException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+import javax.jcr.objectclass.*;
import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.TreeSet;
/**
* An <code>EffectiveObjectClass</code> represents one or more
* <code>ObjectClass</code>es as one 'effective' object class where aggregation
* and inheritance is resolved.
+ * <p>
+ * Instances of <code>EffectiveObjectClass</code> are immutable.
*
* @version $Revision$, $Date$
* @author Stefan Guggisberg
* @since
*/
-class EffectiveObjectClass {
+class EffectiveObjectClass implements Cloneable {
private static Logger log = Logger.getLogger(EffectiveObjectClass.class);
+ private final ObjectClassManagerImpl ocMgr;
+
// list of exlicitly aggregated {i.e. merged) objectclasses
- private final ArrayList mergedOCs;
+ private final TreeSet mergedOCs;
// list of all either explicitly (through aggregation) or implicitly
// (through inheritance) included object classes.
- private final ArrayList allOCs;
+ private final TreeSet allOCs;
+ // map of element definitions
+ private final HashMap elemDefs;
/**
- * Default Constructor.
+ * Constructor.
*/
- EffectiveObjectClass() {
- mergedOCs = new ArrayList();
- allOCs = new ArrayList();
+ private EffectiveObjectClass(ObjectClassManagerImpl ocMgr) {
+ this.ocMgr = ocMgr;
+ mergedOCs = new TreeSet();
+ allOCs = new TreeSet();
+ elemDefs = new HashMap();
+ }
+
+ static EffectiveObjectClass create(ObjectClassManagerImpl ocMgr, String ocName)
+ throws ConstraintViolationException, NoSuchObjectClassException,
RepositoryException {
+ EffectiveObjectClass eoc = new EffectiveObjectClass(ocMgr);
+ eoc.internalMerge(ocName);
+ return eoc;
+ }
+
+ static EffectiveObjectClass create(ObjectClassManagerImpl ocMgr) {
+ return new EffectiveObjectClass(ocMgr);
}
String[] getMergedObjectClasses() {
return (String[]) mergedOCs.toArray(new String[mergedOCs.size()]);
}
- AutoCreatedNode[] getAutoCreatedNodes() {
- return null;
+ String[] getAllObjectClasses() {
+ return (String[]) allOCs.toArray(new String[allOCs.size()]);
+ }
+
+ ElemDef[] getElemDefs() {
+ return (ElemDef[]) elemDefs.entrySet().toArray(new
ElemDef[elemDefs.size()]);
+ }
+
+ boolean hasElemDef(String name) {
+ return elemDefs.containsKey(name);
+ }
+
+ ElemDef getElemDef(String name) {
+ return (ElemDef) elemDefs.get(name);
+ }
+
+ NodeDef[] getNodeDefs() {
+ ArrayList defs = new ArrayList(elemDefs.size());
+ Iterator iter = elemDefs.entrySet().iterator();
+ while (iter.hasNext()) {
+ ElemDef def = (ElemDef) iter.next();
+ if (def.isNode()) {
+ defs.add(def);
+ }
+ }
+ return (NodeDef[]) defs.toArray(new NodeDef[defs.size()]);
+ }
+
+ PropDef[] getPropDefs() {
+ ArrayList defs = new ArrayList(elemDefs.size());
+ Iterator iter = elemDefs.entrySet().iterator();
+ while (iter.hasNext()) {
+ ElemDef def = (ElemDef) iter.next();
+ if (!def.isNode()) {
+ defs.add(def);
+ }
+ }
+ return (PropDef[]) defs.toArray(new PropDef[defs.size()]);
+ }
+
+ boolean containsObjectClass(String ocName) {
+ return allOCs.contains(ocName);
+ }
+
+ EffectiveObjectClass merge(String ocName) throws ConstraintViolationException,
NoSuchObjectClassException, RepositoryException {
+ // create a clone of this instance and perform the merge on
+ // the 'clone' to avoid a potentially inconsistant state
+ // of this instance if an exception is thrown during
+ // the merge.
+ EffectiveObjectClass copy;
+ try {
+ copy = (EffectiveObjectClass) clone();
+ } catch (CloneNotSupportedException e) {
+ // should never get here
+ log.error("internal error", e);
+ throw new InternalError(e.getMessage());
+ }
+ copy.internalMerge(ocName);
+ return copy;
+ }
+
+ EffectiveObjectClass merge(EffectiveObjectClass other) throws
ConstraintViolationException, NoSuchObjectClassException, RepositoryException {
+ // create a clone of this instance and perform the merge on
+ // the 'clone' to avoid a potentially inconsistant state
+ // of this instance if an exception is thrown during
+ // the merge.
+ EffectiveObjectClass copy;
+ try {
+ copy = (EffectiveObjectClass) clone();
+ } catch (CloneNotSupportedException e) {
+ // should never get here
+ log.error("internal error", e);
+ throw new InternalError(e.getMessage());
+ }
+ copy.internalMerge(other);
+ return copy;
+ }
+
+ /**
+ * Internal helper method which merges another objectclass with <i>this</i>
+ * instance.
+ * <p>
+ * Warning: This instance might be in an inconstistent state if an exception
+ * is thrown.
+ * @param ocName
+ * @throws ConstraintViolationException
+ * @throws NoSuchObjectClassException
+ * @throws RepositoryException
+ */
+ synchronized private void internalMerge(String ocName) throws
ConstraintViolationException, NoSuchObjectClassException, RepositoryException {
+ if (containsObjectClass(ocName)) {
+ // ignore
+ log.warn("object class '" + ocName + "' is already contained.");
+ return;
+ }
+
+ ObjectClassDef ocd = null;
+ try {
+ ocd = ocMgr.getObjectClass(ocName).getDefinition();
+ } catch (UnregisteredObjectClassException e) {
+ // should never get here...
+ log.warn("inconsistent state: objectclass '" + ocName + "' exists, but
is not registered.");
+ throw new NoSuchObjectClassException(ocName);
+ }
+
+ PropertyDef[] pda = ocd.getPropertyDefs();
+ for (int i = 0; i < pda.length; i++) {
+ PropertyDef pd = pda[i];
+ String name = pd.getName();
+ if (name == null) {
+ // @todo handle residual porperty sets (name == null)
+ }
+ ElemDef existing = getElemDef(name);
+ if (existing != null) {
+ // conflict
+ String reason = "The property definition for '" + name + "' in
object-class '" + ocName + "' conflicts with object-class '" +
existing.getDefiningObjectClass() + "': name collision";
+ log.error(reason);
+ throw new ConstraintViolationException(reason);
+ }
+ // @todo implement further validations
+
+ // @todo handle residual porperty sets (name == null)
+ elemDefs.put(name, new PropDef(pd, ocName));
+ }
+
+ ChildNodeDef[] nda = ocd.getChildNodeDefs();
+ for (int i = 0; i < nda.length; i++) {
+ ChildNodeDef nd = nda[i];
+ String name = nd.getName();
+ if (name == null) {
+ // @todo handle residual node sets (name == null)
+ }
+ ElemDef existing = getElemDef(nd.getName());
+ if (existing != null) {
+ // conflict
+ String reason = "The child-node definition for '" + nd.getName() +
"' in object-class '" + ocName + "' conflicts with object-class '" +
existing.getDefiningObjectClass() + "': name collision";
+ log.error(reason);
+ throw new ConstraintViolationException(reason);
+ }
+ // @todo implement further validations
+
+ // @todo handle residual node sets (name == null)
+ elemDefs.put(nd.getName(), new NodeDef(nd, ocName));
+ }
+
+ String[] superClasses = ocd.getSuperclasses();
+ for (int i = 0; i < superClasses.length; i++) {
+ internalMerge(superClasses[i]);
+ }
+ mergedOCs.add(ocName);
+ allOCs.add(ocName);
+ }
+
+ /**
+ * Internal helper method which merges another <code>EffectiveObjectClass</code>
+ * instance with <i>this</i> instance.
+ * <p>
+ * Warning: This instance might be in an inconstistent state if an exception
+ * is thrown.
+ * @param other
+ * @throws ConstraintViolationException
+ * @throws RepositoryException
+ */
+ synchronized private void internalMerge(EffectiveObjectClass other) throws
ConstraintViolationException, RepositoryException {
+ String[] oca = other.getAllObjectClasses();
+ boolean foundOverlap = false;
+ for (int i = 0; i < oca.length; i++) {
+ if (containsObjectClass(oca[i])) {
+ // ignore
+ log.warn("object class '" + oca[i] + "' is already contained.");
+ foundOverlap = true;
+ }
+ }
+ if (foundOverlap && (oca.length == allOCs.size())) {
+ // ignore
+ return;
+ }
+
+ PropDef[] pda = other.getPropDefs();
+ for (int i = 0; i < pda.length; i++) {
+ PropDef pd = pda[i];
+ String name = pd.getName();
+ if (name == null) {
+ // @todo handle residual porperty sets (name == null)
+ }
+ ElemDef existing = getElemDef(name);
+ if (existing != null) {
+ // conflict
+ String reason = "The property definition for '" + name + "' in
object-class '" + pd.getDefiningObjectClass() + "' conflicts with object-class '" +
existing.getDefiningObjectClass() + "': name collision";
+ log.error(reason);
+ throw new ConstraintViolationException(reason);
+ }
+ // @todo implement further validations
+
+ // @todo handle residual porperty sets (name == null)
+ elemDefs.put(name, pd);
+ }
+
+ NodeDef[] nda = other.getNodeDefs();
+ for (int i = 0; i < nda.length; i++) {
+ NodeDef nd = nda[i];
+ String name = nd.getName();
+ if (name == null) {
+ // @todo handle residual node sets (name == null)
+ }
+ ElemDef existing = getElemDef(name);
+ if (existing != null) {
+ // conflict
+ String reason = "The child-node definition for '" + name + "' in
object-class '" + nd.getDefiningObjectClass() + "' conflicts with object-class '" +
existing.getDefiningObjectClass() + "': name collision";
+ log.error(reason);
+ throw new ConstraintViolationException(reason);
+ }
+ // @todo implement further validations
+
+ // @todo handle residual node sets (name == null)
+ elemDefs.put(name, nd);
+ }
+
+ for (int i = 0; i < oca.length; i++) {
+ allOCs.add(oca[i]);
+ }
+ oca = other.getMergedObjectClasses();
+ for (int i = 0; i < oca.length; i++) {
+ mergedOCs.add(oca[i]);
+ }
}
-/*
- AutoCreatedProperty[] getAutoCreatedProperties() {
- return null;
+
+ protected Object clone() throws CloneNotSupportedException {
+ return super.clone();
}
-*/
- void merge(ObjectClass oc) throws ConstraintViolationException {
+ //--------------------------------------------------------< inner classes >
+ abstract class ElemDef {
+ protected final String name;
+ protected final String definingObjectClass;
+ protected final boolean autoCreate;
+ protected final int onVersion;
+ protected final boolean readOnly;
+
+ protected final boolean node;
+
+ ElemDef(ChildNodeDef def, String definingObjectClass) {
+ name = def.getName();
+ autoCreate = def.isAutoCreate();
+ onVersion = def.getOnVersion();
+ readOnly = def.isReadOnly();
+ this.definingObjectClass = definingObjectClass;
+ node = true;
+ }
+
+ ElemDef(PropertyDef def, String definingObjectClass) {
+ name = def.getName();
+ autoCreate = def.isAutoCreate();
+ onVersion = def.getOnVersion();
+ readOnly = def.isReadOnly();
+ this.definingObjectClass = definingObjectClass;
+ node = false;
+ }
+
+ String getDefiningObjectClass() {
+ return definingObjectClass;
+ }
+
+ String getName() {
+ return name;
+ }
+
+ boolean isAutoCreate() {
+ return autoCreate;
+ }
+
+ int getOnVersion() {
+ return onVersion;
+ }
+
+ boolean isReadOnly() {
+ return readOnly;
+ }
+
+ boolean isNode() {
+ return node;
+ }
}
- void merge(EffectiveObjectClass eoc) throws ConstraintViolationException {
- // @todo implement
- mergedOCs.add(eoc);
+ class NodeDef extends ElemDef {
+ protected final String[] objectClassConstraint;
+ protected final String[] defaultObjectClasses;
+
+ NodeDef(ChildNodeDef def, String definingObjectClass) {
+ super(def, definingObjectClass);
+ defaultObjectClasses = def.getDefaultObjectClasses();
+ objectClassConstraint = def.getObjectClassConstraint();
+ }
+
+ String[] getDefaultObjectClasses() {
+ return defaultObjectClasses;
+ }
+
+ String[] getObjectClassConstraint() {
+ return objectClassConstraint;
+ }
}
- boolean contains(String ocName) {
- return false;
+ class PropDef extends ElemDef {
+ protected final int type;
+ protected final Value defaultValue;
+ protected final String valueConstraint;
+ protected final boolean mandatory;
+
+ PropDef(PropertyDef def, String definingObjectClass) {
+ super(def, definingObjectClass);
+ type = def.getType();
+ defaultValue = def.getDefaultValue();
+ valueConstraint = def.getValueConstraint();
+ mandatory = def.isMandatory();
+ }
+
+ Value getDefaultValue() {
+ return defaultValue;
+ }
+
+ int getType() {
+ return type;
+ }
+
+ boolean isMandatory() {
+ return mandatory;
+ }
+
+ String getValueConstraint() {
+ return valueConstraint;
+ }
}
}
1.5 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementImpl.java
Index: ElementImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementImpl.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
1.4 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementListener.java
Index: ElementListener.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementListener.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
1.5 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementManager.java
Index: ElementManager.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementManager.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
1.4 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementManagerSupport.java
Index: ElementManagerSupport.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ElementManagerSupport.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
1.5 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/HierarchyNode.java
Index: HierarchyNode.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/HierarchyNode.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
1.4 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/IteratorHelper.java
Index: IteratorHelper.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/IteratorHelper.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
1.6 +5 -5
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.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- NodeImpl.java 3 Jun 2003 12:31:55 -0000 1.5
+++ NodeImpl.java 6 Jun 2003 17:28:23 -0000 1.6
@@ -1444,7 +1444,7 @@
*/
public void remove(Element element)
throws InvalidPathException, AccessDeniedException,
ConstraintViolationException, RepositoryException {
- // @todo handle version nodes and hardlinks
+ // @todo handle version nodes and hardlonks
elemMgr.removeElement(element.getPath());
}
1.6 +4 -5
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/PropertyImpl.java
Index: PropertyImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/PropertyImpl.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- PropertyImpl.java 2 Jun 2003 12:33:08 -0000 1.5
+++ PropertyImpl.java 6 Jun 2003 17:28:23 -0000 1.6
@@ -480,7 +480,6 @@
// @todo determine length of binary data
return -1;
}
-
} catch (RepositoryException e) {
log.error("failed to determine property length", e);
}
1.4 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryFactory.java
Index: RepositoryFactory.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryFactory.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
1.4 +13 -4
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryImpl.java
Index: RepositoryImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RepositoryImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- RepositoryImpl.java 30 May 2003 13:22:36 -0000 1.3
+++ RepositoryImpl.java 6 Jun 2003 17:28:23 -0000 1.4
@@ -81,6 +81,8 @@
private final FileSystem fs;
+ private ObjectClassManagerImpl ocMgr;
+
/**
* Package private constructor
*
@@ -93,6 +95,13 @@
ElementManager getElementManager(TicketImpl ticket) {
// @todo implement synchronization of different per-ticket element managers
return new ElementManager(fs, ticket);
+ }
+
+ synchronized ObjectClassManagerImpl getObjectClassManager() {
+ if (ocMgr == null) {
+ ocMgr = new ObjectClassManagerImpl();
+ }
+ return ocMgr;
}
//-----------------------------------------------------------< Repository >
1.5 +0 -0
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RootContentNode.java
Index: RootContentNode.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/RootContentNode.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
1.4 +5 -6
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/TicketImpl.java
Index: TicketImpl.java
===================================================================
RCS file:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/TicketImpl.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TicketImpl.java 30 May 2003 13:22:36 -0000 1.3
+++ TicketImpl.java 6 Jun 2003 17:28:23 -0000 1.4
@@ -253,8 +253,7 @@
if (impersonator != null) {
return impersonator.getObjectClassManager();
}
- // @todo implement objectclass support
- throw new UnsupportedRepositoryOperationException();
+ return rep.getObjectClassManager();
}
/**
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassDefImpl.java
Index: ObjectClassDefImpl.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassDefImpl.java,v
1.1 2003/06/06 17:28:23 stefan Exp $
* $Revision: 1.1 $
* $Date: 2003/06/06 17:28:23 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.jcr.core;
import org.apache.log4j.Logger;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.objectclass.*;
/**
* An <code>ObjectClassDefImpl</code> ...
*
* @version $Revision: 1.1 $, $Date: 2003/06/06 17:28:23 $
* @author Stefan Guggisberg
* @since
*/
class ObjectClassDefImpl implements ObjectClassDef {
private static Logger log = Logger.getLogger(ObjectClassDefImpl.class);
private final ObjectClassManagerImpl ocMgr;
private final Node node;
private String name;
private boolean registered;
private ObjectClass oc;
/**
* Package private constructor
*/
ObjectClassDefImpl(ObjectClassManagerImpl ocMgr, Node node) {
this.ocMgr = ocMgr;
this.node = node;
try {
name = node.getProperty("jcr:Name").toString();
} catch (RepositoryException e) {
name = "";
}
if (name.length() > 0) {
try {
oc = this.ocMgr.getObjectClass(name);
registered = true;
} catch (NoSuchObjectClassException e) {
registered = false;
}
} else {
registered = false;
}
}
//-------------------------------------------------------< ObjectClassDef >
/**
* @see ObjectClassDef#getChildNodeDefs
*/
public ChildNodeDef[] getChildNodeDefs() throws RepositoryException {
// @todo implement getChildNodeDefs
return new ChildNodeDef[0];
}
/**
* @see ObjectClassDef#getDefinitionNode
*/
public Node getDefinitionNode() throws RepositoryException {
// @todo implement getDefinitionNode
return null;
}
/**
* @see ObjectClassDef#getName
*/
public String getName() throws RepositoryException {
return name;
}
/**
* @see ObjectClassDef#getPropertyDefs
*/
public PropertyDef[] getPropertyDefs() throws RepositoryException {
// @todo implement getPropertyDefs
return new PropertyDef[0];
}
/**
* @see ObjectClassDef#getRegisteredObjectClass
*/
public ObjectClass getRegisteredObjectClass() {
return oc;
}
/**
* @see ObjectClassDef#getSuperclasses
*/
public String[] getSuperclasses() throws RepositoryException {
// @todo implement getSuperclasses
return new String[0];
}
/**
* @see ObjectClassDef#register
*/
public ObjectClass register() throws InvalidObjectClassDefException,
ObjectClassExistsException, RepositoryException {
// @todo implement register
return null;
}
/**
* @see ObjectClassDef#setChildNodeDefs
*/
public void setChildNodeDefs(ChildNodeDef[] defs) throws
ObjectClassRegisteredException, RepositoryException {
// @todo implement setChildNodeDefs
}
/**
* @see ObjectClassDef#setName
*/
public void setName(String name) throws ObjectClassRegisteredException,
RepositoryException {
// @todo implement setName
}
/**
* @see ObjectClassDef#setPropertyDefs
*/
public void setPropertyDefs(PropertyDef[] defs) throws
ObjectClassRegisteredException, RepositoryException {
// @todo implement setPropertyDefs
}
/**
* @see ObjectClassDef#setSuperclasses
*/
public void setSuperclasses(String[] names) throws
ObjectClassRegisteredException, RepositoryException {
// @todo implement setSuperclasses
}
}
1.4 +34 -55
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassImpl.java
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassManagerImpl.java
Index: ObjectClassManagerImpl.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/ObjectClassManagerImpl.java,v
1.1 2003/06/06 17:28:23 stefan Exp $
* $Revision: 1.1 $
* $Date: 2003/06/06 17:28:23 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.slide.jcr.core;
import org.apache.log4j.Logger;
import javax.jcr.*;
import javax.jcr.access.AccessDeniedException;
import javax.jcr.objectclass.*;
import java.util.*;
/**
* A <code>ObjectClassManagerImpl</code> ...
*
* @version $Revision: 1.1 $, $Date: 2003/06/06 17:28:23 $
* @author Stefan Guggisberg
* @since
*/
class ObjectClassManagerImpl implements ObjectClassManager {
private static Logger log = Logger.getLogger(ObjectClassManagerImpl.class);
// cache of pre-build aggregations of object classes
private final TreeMap aggregates;
/**
* Package private constructor
*/
ObjectClassManagerImpl() {
aggregates = new TreeMap();
}
/**
*
* @param ocNames
* @return
*/
synchronized EffectiveObjectClass getEffectiveObjectClass(String[] ocNames)
throws ConstraintViolationException, NoSuchObjectClassException,
RepositoryException {
EffectiveObjectClass result = EffectiveObjectClass.create(this);
WeightedKey key = new WeightedKey(ocNames);
// short-cut for optimization
if (aggregates.containsKey(key)) {
return (EffectiveObjectClass) aggregates.get(key);
}
// build list of 'best' existing sub-aggregates
ArrayList tmpResults = new ArrayList();
while (key.size() > 0) {
// check if we've already build this aggregate
if (aggregates.containsKey(key)) {
tmpResults.add(aggregates.get(key));
// subtract the result from the temporary key
// (which is 'empty' now)
key = key.subtract(key);
break;
}
// walk list of existing aggregates sorted by 'weight' of
// aggregate (i.e. the cost of building it)
boolean foundSubResult = false;
Iterator iter = aggregates.keySet().iterator();
while (iter.hasNext()) {
WeightedKey k = (WeightedKey) iter.next();
if (key.contains(k)) {
tmpResults.add(aggregates.get(k));
// subtract the result from the temporary key
key = key.subtract(k);
foundSubResult = true;
break;
}
}
if (!foundSubResult) {
// no matching sub-aggregates found:
// build aggregate of remaining object classes
String[] remainder = key.toArray();
for (int i = 0; i < remainder.length; i++) {
result = result.merge(remainder[i]);
// add to result list
tmpResults.add(result);
// store intermediate result
WeightedKey k = new WeightedKey(new String[]{remainder[i]});
aggregates.put(k, result);
}
break;
}
}
// merge the sub-aggregates into new effective objectclass
for (int i = 0; i < tmpResults.size(); i++) {
result = result.merge((EffectiveObjectClass) tmpResults.get(i));
// store intermediate result
WeightedKey k = new WeightedKey(result.getMergedObjectClasses());
aggregates.put(k, result);
}
// we're done
return result;
}
//---------------------------------------------------< ObjectCLassManager >
/**
* @see ObjectClassManager#createObjectClassDef
*/
public ObjectClassDef createObjectClassDef(String absPath) throws
InvalidPathException, ElementExistsException, ConstraintViolationException,
AccessDeniedException, RepositoryException {
// @todo implement createObjectClassDef
return null;
}
/**
* @see ObjectClassManager#getAllObjectClasses
*/
public ObjectClassIterator getAllObjectClasses() throws RepositoryException {
// @todo implement getAllObjectClasses
return new IteratorHelper(Collections.EMPTY_LIST.iterator());
}
/**
* @see ObjectClassManager#getObjectClass
*/
public ObjectClass getObjectClass(String name) throws NoSuchObjectClassException
{
// @todo implement getObjectClass
return null;
}
/**
* @see ObjectClassManager#getObjectClassDef
*/
public ObjectClassDef getObjectClassDef(Node node) throws
ConstraintViolationException, RepositoryException {
// @todo implement getObjectClassDef
return null;
}
//--------------------------------------------------------< inner classes >
/**
* A <code>WeightedKey</code> uniquely identifies
* a combination (i.e. an aggregation) of one or more objectclasses.
* The weight is an indicator for the cost involved in building such an
* aggregate (an aggregation multiple complex objectclasses with deep
* inheritance trees is more costly to build/validate than an agreggation
* of two very simple objectclasses with just one property definition each).
* A very simple (and not very accurate) approximation of the weight would
* be the number of aggreagted objectclasses (ignoring inheritance and
* complexity of each involved objectclass).
* <p>
* The more accurate the weight definition, the more efficient is the
* the building of new aggregates.
* <p>
* Let's assume we have an aggregation of objectclasses named "b", "a" and "c".
* Its key would be "[a][b][c]", the pattern ".*[a].*[b].*[c].*" and the weight
3.
*
* @author Stefan Guggisberg
*/
static class WeightedKey implements Comparable {
private final TreeSet set;
private final int weight;
/**
*
* @param ocNames
*/
WeightedKey(String[] ocNames) {
this(ocNames, ocNames.length);
}
/**
*
* @param ocNames
* @param weight
*/
WeightedKey(String[] ocNames, int weight) {
this.weight = weight;
set = new TreeSet();
for (int i = 0; i < ocNames.length; i++) {
// add name to this sorted set
set.add(ocNames[i]);
}
}
/**
*
* @param ocNames
*/
WeightedKey(Collection ocNames) {
this(ocNames, ocNames.size());
}
/**
*
* @param ocNames
* @param weight
*/
WeightedKey(Collection ocNames, int weight) {
this.weight = weight;
set = new TreeSet(ocNames);
}
/**
* The key is the string representation of this sorted set
* (e.g. the key for a set containing entries "c", "b" and "a" would
* be "[a], [b], [c]").
*
* @see AbstractCollection#toString
*
* @return string representation of this sorted set
*/
String getKey() {
return set.toString();
}
/**
*
* @return
*/
int getWeight() {
return weight;
}
int size() {
return set.size();
}
Iterator iterator() {
return Collections.unmodifiableSortedSet(set).iterator();
}
Set getSet() {
return Collections.unmodifiableSortedSet(set);
}
String[] toArray() {
return (String[]) set.toArray(new String[set.size()]);
}
boolean contains(WeightedKey otherKey) {
return set.containsAll(otherKey.getSet());
}
WeightedKey subtract(WeightedKey otherKey) {
Set tmp = (Set) set.clone();
tmp.removeAll(otherKey.getSet());
return new WeightedKey(tmp);
}
/**
* The resulting sort-order is: 1. descending weight, 2. ascending key
* (i.e. string representation of this sorted set).
* @param o
* @return
*/
public int compareTo(Object o) {
WeightedKey other = (WeightedKey) o;
if (getWeight() > other.getWeight()) {
return -1;
} else if (getWeight() < other.getWeight()) {
return 1;
}
return getKey().compareTo(other.getKey());
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]