1 5 package org.exoplatform.services.jcr.impl.core.nodetype; 6 7 import java.util.ArrayList ; 8 9 import org.apache.commons.logging.Log; 10 import org.exoplatform.services.log.LogUtil; 11 12 import javax.jcr.Value; 13 import javax.jcr.PropertyType; 14 import javax.jcr.nodetype.*; 15 16 22 abstract public class NodeTypeImpl implements NodeType { 23 24 protected Log log; 25 26 protected String name; 27 protected boolean mixin; 28 protected NodeType[] declaredSupertypes; 29 protected PropertyDef[] declaredPropertyDefs; 30 protected NodeDef[] declaredNodeDefs; 31 32 public NodeTypeImpl() { 33 log = LogUtil.getLog("org.exoplatform.services.jcr"); 34 } 35 36 37 41 public String getName() { 42 return name; 43 } 44 45 51 public boolean isMixin() { 52 return mixin; 53 } 54 55 62 public NodeType[] getSupertypes() { 63 ArrayList stypesList = new ArrayList (); 64 65 fillSupertypes(stypesList, this); 66 if (stypesList.size() > 0) { 67 NodeType[] supertypes = new NodeType[stypesList.size()]; 68 for (int i = 0; i < stypesList.size(); i++) { 69 supertypes[i] = (NodeType) stypesList.get(i); 70 } 71 return supertypes; 72 } 73 return new NodeType[0]; 74 } 75 76 87 public NodeType[] getDeclaredSupertypes() { 88 return declaredSupertypes; 89 } 90 91 98 public PropertyDef[] getPropertyDefs() { 99 ArrayList propertyDefsList = new ArrayList (); 100 101 if (declaredPropertyDefs != null) { 102 for (int i = 0; i < declaredPropertyDefs.length; i++) { 103 propertyDefsList.add(declaredPropertyDefs[i]); 104 } 105 } 106 NodeType[] supertypes = getSupertypes(); 107 if (supertypes != null) { 108 for (int i = 0; i < supertypes.length; i++) { 109 if (supertypes[i].getDeclaredPropertyDefs() != null) { 110 for (int j = 0; j < supertypes[i].getDeclaredPropertyDefs().length; j++) { 111 if (!propertyDefsList.contains(supertypes[i].getDeclaredPropertyDefs()[j])) 112 propertyDefsList.add(supertypes[i].getDeclaredPropertyDefs()[j]); 113 } 114 } 115 } 116 } 117 118 if (propertyDefsList.size() > 0) { 119 PropertyDef[] propertyDefs = new PropertyDef[propertyDefsList.size()]; 120 for (int i = 0; i < propertyDefsList.size(); i++) { 121 propertyDefs[i] = (PropertyDef) propertyDefsList.get(i); 122 } 123 return propertyDefs; 124 } 125 return null; 126 } 127 128 133 public PropertyDef[] getDeclaredPropertyDefs() { 134 return declaredPropertyDefs; 135 } 136 137 144 public NodeDef[] getChildNodeDefs() { 145 ArrayList nodeDefsList = new ArrayList (); 146 147 if (declaredNodeDefs != null) 148 for (int i = 0; i < declaredNodeDefs.length; i++) 149 nodeDefsList.add(declaredNodeDefs[i]); 150 151 NodeType[] supertypes = getSupertypes(); 152 if (supertypes != null) { 153 for (int i = 0; i < supertypes.length; i++) { 154 if (supertypes[i].getDeclaredChildNodeDefs() != null) { 155 for (int j = 0; j < supertypes[i].getDeclaredChildNodeDefs().length; j++) { 156 if (!nodeDefsList.contains(supertypes[i].getDeclaredChildNodeDefs()[j])) { 157 nodeDefsList.add(supertypes[i].getDeclaredChildNodeDefs()[j]); 158 } 159 } 160 } 161 } 162 } 163 164 if (nodeDefsList.size() > 0) { 165 NodeDef[] childNodeDefs = new NodeDef[nodeDefsList.size()]; 166 for (int i = 0; i < nodeDefsList.size(); i++) { 167 childNodeDefs[i] = (NodeDef) nodeDefsList.get(i); 168 } 169 return childNodeDefs; 170 } 171 return new NodeDef[0]; 172 } 173 174 179 public NodeDef[] getDeclaredChildNodeDefs() { 180 return declaredNodeDefs; 181 } 182 183 191 public boolean canSetProperty(String propertyName, Value value) { 192 try { 193 checkSetProperty(propertyName, value); 194 return true; 195 } catch (ConstraintViolationException e) { 196 return false; 197 } 198 } 199 200 207 public boolean canAddChildNode(String childNodeName) { 208 try { 209 checkAddChildNode(childNodeName); 210 return true; 211 } catch (ConstraintViolationException e) { 212 return false; 213 } 214 } 215 216 226 public boolean canAddChildNode(String childNodeName, String nodeTypeName) { 227 try { 228 checkAddChildNode(childNodeName, nodeTypeName); 229 return true; 230 } catch (ConstraintViolationException e) { 231 return false; 232 } 233 } 234 235 241 public boolean checkRemoveItem(String itemName) { 242 try { 243 checkRemove(itemName); 244 return true; 245 } catch (ConstraintViolationException e) { 246 return false; 247 } 248 } 249 250 public PropertyDef getPropertyDef(String name) { 251 int residualNb = 0; 252 PropertyDef residualProperty = null; 253 for (int i = 0; i < getPropertyDefs().length; i++) { 254 PropertyDef prop = getPropertyDefs()[i]; 255 if (prop.getName() != null) { 256 if (prop.getName().equals(name)) 257 return prop; 258 } else { 259 residualNb++; 261 residualProperty = prop; 262 } 263 } 264 if (residualNb == 1) 265 return residualProperty; 266 return null; 267 } 268 269 270 public NodeDef getChildNodeDef(String name) { 271 NodeDef[] nodeDefs = getChildNodeDefs(); 272 for (int i = 0; i < nodeDefs.length; i++) { 273 NodeDef nodeDef = getChildNodeDefs()[i]; 274 if (nodeDef.getName() != null) { 275 if (nodeDef.getName().equals(name)) 276 return nodeDef; 277 } 278 } 279 280 for (int i = 0; i < nodeDefs.length; i++) { 282 NodeDef nodeDef = nodeDefs[i]; 283 if (nodeDef.getName() == null) { 284 return nodeDef; 285 } 286 } 287 return null; 288 } 289 290 public String toString() { 291 return "NodeType: " + name; 292 } 293 294 public boolean equals(Object obj) { 295 if (!(obj instanceof NodeTypeImpl)) 296 return false; 297 return name == ((NodeType) obj).getName(); 298 } 299 300 301 307 public void checkSetProperty(String propertyName, Value value) throws ConstraintViolationException { 308 boolean residualFlag = false; 309 for (int i = 0; i < getPropertyDefs().length; i++) { 310 PropertyDef prop = getPropertyDefs()[i]; 311 if (prop.getName() == null) { 312 residualFlag = true; 313 } else if (prop.getName().equals(propertyName)) { 314 if (prop.isReadOnly()) 315 throw new ConstraintViolationException("Could not set Read-Only Property <" + propertyName + "> !"); 316 if (prop.getRequiredType() != PropertyType.UNDEFINED 317 && value.getType() != prop.getRequiredType()) 318 throw new ConstraintViolationException("Invalid required property type <" + 319 prop.getRequiredType() + "> for Property <" + propertyName + "> !"); 320 if (!checkValueConstraint(prop.getValueConstraint(), value)) 321 throw new ConstraintViolationException("Value Constraint <" + prop.getValueConstraint() 322 + "> violated for Property <" + propertyName + "> !"); 323 if (prop.getName().indexOf("[") > -1 && !prop.isMultiple()) 324 throw new ConstraintViolationException("Multiplicity is not supported for Property <" 325 + propertyName + "> !"); 326 return; 327 } 328 } 329 if (residualFlag) 330 return; 331 else 332 throw new ConstraintViolationException("Property <" + propertyName + "> is not allowed!"); 333 334 } 335 336 343 public void checkAddChildNode(String childNodeName) throws ConstraintViolationException { 344 checkAddChildNode(childNodeName, null); 345 } 346 347 356 public void checkAddChildNode(String childNodeName, String nodeTypeName) throws ConstraintViolationException { 357 if (getChildNodeDefs() == null) 358 throw new ConstraintViolationException("Node <" + childNodeName + "> is not allowed!"); 359 360 int residual = 0; 361 NodeDef residualDef = null; 362 363 for (int i = 0; i < getChildNodeDefs().length; i++) { 364 NodeDef def = getChildNodeDefs()[i]; 365 if (def.getName() == null) { 366 residualDef = def; 367 residual++; 368 } else if (def.getName().equals(childNodeName)) { 369 if (def.isReadOnly()) { 370 log.debug("NodeType.checkAddChildNode(): Could not add Read-Only Node <" + childNodeName + "> !"); 371 throw new ConstraintViolationException("NodeType.checkAddChildNode(): Could not add Read-Only Node <" + childNodeName + "> !"); 372 } 373 374 if (def.getName().indexOf("[") > -1 && !def.allowSameNameSibs()) { 375 log.debug("NodeType.checkAddChildNode(): Multiplicity is not supported for Node <" + childNodeName + "> !"); 376 throw new ConstraintViolationException("NodeType.checkAddChildNode(): Multiplicity is not supported for Node <" + childNodeName + "> !"); 377 } 378 379 if (nodeTypeName != null) { 380 NodeDef[] childNodeDefs = getChildNodeDefs(); 381 for (int j = 0; j < childNodeDefs.length; j++) { 382 NodeDef childNodeDef = childNodeDefs[j]; 383 NodeType requiredNodeType = childNodeDef.getDefaultPrimaryType(); 384 if (nodeTypeName.equals(requiredNodeType.getName())) { 385 return; 386 } 387 } 388 log.debug("NodeType.checkAddChildNode(): Incompatible node type <" + nodeTypeName + ">"); 389 throw new ConstraintViolationException("NodeType.checkAddChildNode(): Incompatible node type <" + nodeTypeName + ">"); 390 } 391 } 392 } 393 if (residual == 1) { 394 if (nodeTypeName != null) { 395 NodeType[] requiredNodeTypes = residualDef.getRequiredPrimaryTypes(); 396 for (int i = 0; i < requiredNodeTypes.length; i++) { 397 String residualNodeTypeName = requiredNodeTypes[i].getName(); 398 399 NodeType testNodeType; 400 try { 401 testNodeType = NodeTypeManagerImpl.getInstance().getNodeType(nodeTypeName); 402 } catch (NoSuchNodeTypeException e) { 403 throw new ConstraintViolationException("No such node: "+nodeTypeName); 404 } 405 406 if (isSameOrSubType(requiredNodeTypes[i], testNodeType)) 407 return; 408 log.debug("NodeType.checkAddChildNode(): Incompatible node type for residual(1) <" + nodeTypeName + ">"); 409 throw new ConstraintViolationException("NodeType.checkAddChildNode(): Incompatible node type for residual <" + nodeTypeName + ">"); 410 } 411 } 412 } else if (residual > 1) { 413 if (nodeTypeName != null) { 414 for (int i = 0; i < getChildNodeDefs().length; i++) { 415 NodeDef def = getChildNodeDefs()[i]; 416 if (def.getName() == null) { 417 if (nodeTypeName.equals(def.getDeclaringNodeType().getName())) 418 return; 419 } 420 } 421 } 422 log.debug("NodeType.checkAddChildNode(): Incompatible node type for residual>0 <" + nodeTypeName + ">"); 423 throw new ConstraintViolationException("NodeType.checkAddChildNode(): Incompatible node type for residual>0 <" + nodeTypeName + ">"); 424 } else { 425 log.debug("NodeType.checkAddChildNode(): Node <" + childNodeName + "> is not allowed!"); 426 throw new ConstraintViolationException("NodeType.checkAddChildNode(): Node <" + childNodeName + "> is not allowed!"); 427 } 428 429 } 430 431 436 public void checkRemove(String childNodeName) throws ConstraintViolationException { 437 438 boolean residualFlag = false; 439 440 for (int i = 0; i < getChildNodeDefs().length; i++) { 441 NodeDef def = getChildNodeDefs()[i]; 442 if (def.getName() == null) { 443 residualFlag = true; 444 } else if (def.getName().equals(childNodeName)) { 445 if (def.isReadOnly()) 446 throw new ConstraintViolationException("Could not remove Read-Only Node <" + childNodeName + "> !"); 447 if (def.isMandatory()) 448 throw new ConstraintViolationException("Could not remove Mandatory Node <" + childNodeName + "> !"); 449 } 450 } 451 if (residualFlag) 452 return; 453 else 454 throw new ConstraintViolationException("Node <" + childNodeName + "> is not allowed!"); 455 456 } 457 458 protected boolean isBase() { 459 return getSupertypes().length == 0; 460 } 461 462 protected boolean checkValueConstraint(String constraint, Value value) { 463 return true; 464 } 465 466 protected void fillSupertypes(ArrayList list, NodeType subtype) { 467 if (subtype.getDeclaredSupertypes() != null) { 468 for (int i = 0; i < subtype.getDeclaredSupertypes().length; i++) { 469 list.add(subtype.getDeclaredSupertypes()[i]); 470 fillSupertypes(list, subtype.getDeclaredSupertypes()[i]); 471 } 472 } 473 474 } 475 476 public static boolean isSameOrSubType(NodeType superType, NodeType subType) { 477 if (superType.getName().equals(subType.getName())) 478 return true; 479 else { 480 481 NodeType[] superTypes = subType.getSupertypes(); 482 490 for (int j = 0; j < superTypes.length; j++) { 491 NodeType testSuperType = superTypes[j]; 492 if (testSuperType.getName().equals(superType.getName())) 493 return true; 494 } 495 } 496 return false; 497 } 498 499 } 500 | Popular Tags |