001: /*
002: * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.jcr.base;
031:
032: import javax.jcr.PropertyType;
033: import javax.jcr.Value;
034: import javax.jcr.nodetype.NodeDefinition;
035: import javax.jcr.nodetype.NodeType;
036: import javax.jcr.nodetype.PropertyDefinition;
037: import javax.jcr.version.OnParentVersionAction;
038: import java.util.ArrayList;
039:
040: /**
041: * Represents a node type.
042: */
043: public class BaseNodeType implements NodeType {
044: public static final BaseNodeType MIX_REFERENCEABLE;
045:
046: public static final BaseNodeType NT_BASE;
047:
048: public static final BaseNodeType NT_HIERARCHY_NODE;
049: public static final BaseNodeType NT_FILE;
050: public static final BaseNodeType NT_FOLDER;
051: public static final BaseNodeType NT_RESOURCE;
052:
053: private final String _name;
054:
055: private final NodeType[] _declaredSuperTypes;
056:
057: private final NodeType[] _super Types;
058:
059: private boolean _isMixin;
060:
061: private boolean _hasOrderableChildNodes;
062:
063: private String _primaryItemName;
064:
065: private ArrayList<PropertyDefinition> _properties = new ArrayList<PropertyDefinition>();
066:
067: private ArrayList<NodeDefinition> _childNodes = new ArrayList<NodeDefinition>();
068:
069: public BaseNodeType(String name, NodeType[] declaredSuperTypes) {
070: _name = name;
071: _declaredSuperTypes = declaredSuperTypes;
072:
073: ArrayList<NodeType> super Types = new ArrayList<NodeType>();
074:
075: for (NodeType type : declaredSuperTypes) {
076: if (!super Types.contains(type))
077: super Types.add(type);
078:
079: for (NodeType parentType : type.getSupertypes()) {
080: if (!super Types.contains(parentType))
081: super Types.add(parentType);
082: }
083: }
084:
085: _super Types = new NodeType[super Types.size()];
086: super Types.toArray(_super Types);
087: }
088:
089: public BaseNodeType(String name, NodeType super Type) {
090: this (name, new NodeType[] { super Type });
091: }
092:
093: /**
094: * Returns the node type's name.
095: */
096: public String getName() {
097: return _name;
098: }
099:
100: /**
101: * Returns true for a mixin node type.
102: */
103: public boolean isMixin() {
104: return _isMixin;
105: }
106:
107: /**
108: * Set true for a mixin node type.
109: */
110: public void setMixin(boolean isMixin) {
111: _isMixin = isMixin;
112: }
113:
114: /**
115: * Returns true if this node type has orderable children.
116: */
117: public boolean hasOrderableChildNodes() {
118: return _hasOrderableChildNodes;
119: }
120:
121: /**
122: * SEt true if this node type has orderable children.
123: */
124: public void setHasOrderableChildNodes(boolean hasOrder) {
125: _hasOrderableChildNodes = hasOrder;
126: }
127:
128: /**
129: * Returns the main item name.
130: */
131: public String getPrimaryItemName() {
132: return _primaryItemName;
133: }
134:
135: /**
136: * Returns the main item type.
137: */
138: public void setPrimaryItemName(String name) {
139: _primaryItemName = name;
140: }
141:
142: /**
143: * Returns all supertypes of the node type.
144: */
145: public NodeType[] getSupertypes() {
146: return _super Types;
147: }
148:
149: /**
150: * Returns the immediate supertypes of the node type.
151: */
152: public NodeType[] getDeclaredSupertypes() {
153: return _declaredSuperTypes;
154: }
155:
156: /**
157: * Returns true if the given node type is valid.
158: */
159: public boolean isNodeType(String nodeTypeName) {
160: return false;
161: }
162:
163: /**
164: * Returns the properties defined for the node.
165: */
166: public PropertyDefinition[] getPropertyDefinitions() {
167: return getDeclaredPropertyDefinitions();
168: }
169:
170: /**
171: * Returns the immediate properties defined for the node.
172: */
173: public PropertyDefinition[] getDeclaredPropertyDefinitions() {
174: PropertyDefinition[] props;
175:
176: props = new PropertyDefinition[_properties.size()];
177: _properties.toArray(props);
178:
179: return props;
180: }
181:
182: /**
183: * Adds a property definition.
184: */
185: public void addProperty(PropertyDefinition prop) {
186: _properties.add(prop);
187: }
188:
189: /**
190: * Returns the allowed children.
191: */
192: public NodeDefinition[] getChildNodeDefinitions() {
193: return getDeclaredChildNodeDefinitions();
194: }
195:
196: /**
197: * Returns the direct children.
198: */
199: public NodeDefinition[] getDeclaredChildNodeDefinitions() {
200: NodeDefinition[] children;
201:
202: children = new NodeDefinition[_childNodes.size()];
203: _childNodes.toArray(children);
204:
205: return children;
206: }
207:
208: /**
209: * Adds a child node.
210: */
211: public void addChildNode(NodeDefinition child) {
212: _childNodes.add(child);
213: }
214:
215: /**
216: * Returns true if the given property can be set with the given value.
217: */
218: public boolean canSetProperty(String propertyName, Value value) {
219: return false;
220: }
221:
222: /**
223: * Returns true if the given property can be set with the given value.
224: */
225: public boolean canSetProperty(String propertyName, Value[] values) {
226: return false;
227: }
228:
229: /**
230: * Returns true if this node type can add a child node.
231: */
232: public boolean canAddChildNode(String childNodeName) {
233: return false;
234: }
235:
236: /**
237: * Returns true if this node type can add a child node with the given type..
238: */
239: public boolean canAddChildNode(String childNodeName,
240: String nodeTypeName) {
241: return false;
242: }
243:
244: /**
245: * Returns true if this node type can remove an item.
246: */
247: public boolean canRemoveItem(String itemName) {
248: return false;
249: }
250:
251: public int hashCode() {
252: return getName().hashCode();
253: }
254:
255: public boolean equals(Object o) {
256: if (this == o)
257: return true;
258: else if (!(o instanceof BaseNodeType))
259: return false;
260:
261: BaseNodeType nodeType = (BaseNodeType) o;
262:
263: return getName().equals(nodeType.getName());
264: }
265:
266: public String toString() {
267: return "BaseNodeType[" + getName() + "]";
268: }
269:
270: static {
271: BasePropertyDefinition prop;
272: BaseNodeDefinition child;
273:
274: // mix:referenceable
275:
276: MIX_REFERENCEABLE = new BaseNodeType("mix:referenceable",
277: new NodeType[0]);
278:
279: // nt:base
280:
281: NT_BASE = new BaseNodeType("nt:base", new NodeType[0]);
282:
283: prop = new BasePropertyDefinition("jcr:primaryType", NT_BASE,
284: PropertyType.NAME);
285: prop.setAutoCreated(true);
286: prop.setMandatory(true);
287: prop.setOnParentVersion(OnParentVersionAction.COMPUTE);
288: prop.setProtected(true);
289: NT_BASE.addProperty(prop);
290:
291: prop = new BasePropertyDefinition("jcr:mixinTypes", NT_BASE,
292: PropertyType.NAME);
293: prop.setOnParentVersion(OnParentVersionAction.COMPUTE);
294: prop.setProtected(true);
295: prop.setMultiple(true);
296: NT_BASE.addProperty(prop);
297:
298: // nt:unstructured - XXX: skip
299:
300: // nt:hierarchyNode
301:
302: NT_HIERARCHY_NODE = new BaseNodeType("nt:hierarchyNode",
303: NT_BASE);
304:
305: prop = new BasePropertyDefinition("jcr:created",
306: NT_HIERARCHY_NODE, PropertyType.DATE);
307: prop.setAutoCreated(true);
308: prop.setOnParentVersion(OnParentVersionAction.INITIALIZE);
309: prop.setProtected(true);
310: NT_HIERARCHY_NODE.addProperty(prop);
311:
312: // nt:file
313:
314: NT_FILE = new BaseNodeType("nt:file", NT_HIERARCHY_NODE);
315: NT_FILE.setPrimaryItemName("jcr:content");
316:
317: child = new BaseNodeDefinition("jcr:content", NT_FILE);
318: child.setRequiredPrimaryTypes(new NodeType[] { NT_BASE });
319: child.setMandatory(true);
320: NT_FILE.addChildNode(child);
321:
322: // nt:linkedFile - XXX: skip
323:
324: // nt:folder
325:
326: NT_FOLDER = new BaseNodeType("nt:folder", NT_HIERARCHY_NODE);
327:
328: child = new BaseNodeDefinition("*", NT_FOLDER);
329: child
330: .setRequiredPrimaryTypes(new NodeType[] { NT_HIERARCHY_NODE });
331: child.setOnParentVersion(OnParentVersionAction.VERSION);
332:
333: // nt:resource
334:
335: NT_RESOURCE = new BaseNodeType("nt:resource", new NodeType[] {
336: NT_HIERARCHY_NODE, MIX_REFERENCEABLE });
337: NT_RESOURCE.setPrimaryItemName("jcr:data");
338:
339: prop = new BasePropertyDefinition("jcr:encoding", NT_RESOURCE,
340: PropertyType.STRING);
341: NT_FOLDER.addProperty(prop);
342:
343: prop = new BasePropertyDefinition("jcr:mimeType", NT_RESOURCE,
344: PropertyType.STRING);
345: prop.setMandatory(true);
346: NT_FOLDER.addProperty(prop);
347:
348: prop = new BasePropertyDefinition("jcr:data", NT_RESOURCE,
349: PropertyType.BINARY);
350: prop.setMandatory(true);
351: NT_FOLDER.addProperty(prop);
352:
353: prop = new BasePropertyDefinition("jcr:lastModified",
354: NT_RESOURCE, PropertyType.DATE);
355: prop.setMandatory(true);
356: prop.setOnParentVersion(OnParentVersionAction.IGNORE);
357: NT_FOLDER.addProperty(prop);
358: }
359: }
|