1 5 6 package org.exoplatform.services.jcr.impl.core; 7 8 import java.io.ByteArrayInputStream ; 9 import java.io.IOException ; 10 import java.io.OutputStream ; 11 import java.util.ArrayList ; 12 import java.util.Iterator ; 13 import java.util.List ; 14 import java.util.Properties ; 15 16 import javax.jcr.ActionVetoedException; 17 import javax.jcr.ItemExistsException; 18 import javax.jcr.NamespaceRegistry; 19 import javax.jcr.Node; 20 import javax.jcr.PathNotFoundException; 21 import javax.jcr.Property; 22 import javax.jcr.PropertyIterator; 23 import javax.jcr.PropertyType; 24 import javax.jcr.RepositoryException; 25 import javax.jcr.Ticket; 26 import javax.jcr.UnsupportedRepositoryOperationException; 27 import javax.jcr.Workspace; 28 import javax.jcr.access.AccessDeniedException; 29 import javax.jcr.access.AccessManager; 30 import javax.jcr.lock.LockCapabilities; 31 import javax.jcr.nodetype.ConstraintViolationException; 32 import javax.jcr.nodetype.NodeTypeManager; 33 import javax.jcr.observation.ObservationManager; 34 import javax.jcr.query.QueryManager; 35 import javax.xml.parsers.SAXParser ; 36 import javax.xml.parsers.SAXParserFactory ; 37 38 import org.apache.commons.codec.binary.Base64; 39 import org.apache.commons.logging.Log; 40 import org.exoplatform.container.PortalContainer; 41 import org.exoplatform.services.jcr.core.ItemLocation; 42 import org.exoplatform.services.jcr.impl.core.nodetype.NodeTypeManagerImpl; 43 import org.exoplatform.services.jcr.impl.core.query.QueryManagerImpl; 44 import org.exoplatform.services.jcr.impl.util.StringConverter; 45 import org.exoplatform.services.jcr.impl.util.XMLWriter; 46 import org.exoplatform.services.jcr.storage.RepositoryManager; 47 import org.exoplatform.services.jcr.storage.WorkspaceContainer; 48 import org.exoplatform.services.jcr.util.PathUtil; 49 import org.exoplatform.services.log.LogUtil; 50 import org.xml.sax.ContentHandler ; 51 import org.xml.sax.InputSource ; 52 import org.xml.sax.SAXException ; 53 import org.xml.sax.XMLReader ; 54 55 64 65 public class WorkspaceImpl implements Workspace { 66 67 public static final String ROOT_PATH = "/"; 68 69 protected Log log; 70 71 private Ticket ticket; 72 private WorkspaceContainer serverContainer; 73 private String workspaceName; 74 75 public WorkspaceImpl(String workspaceName, Ticket ticket) throws RepositoryException { 76 log = LogUtil.getLog("org.exoplatform.services.jcr"); 77 this.workspaceName = workspaceName; 78 this.ticket = ticket; 79 this.serverContainer = ((RepositoryImpl) ticket.getRepository()).getContainer(workspaceName); 80 } 81 82 87 public Ticket getTicket() { 88 return ticket; 89 } 90 91 92 115 public void clone(String srcAbsPath, String destAbsPath, String destWorkspace, boolean shallow) 116 throws ConstraintViolationException, AccessDeniedException, PathNotFoundException, 117 ItemExistsException, ActionVetoedException, RepositoryException { 118 119 NodeImpl node = (NodeImpl) serverContainer.getNodeByPath(srcAbsPath); 120 121 if (node == null) 122 throw new PathNotFoundException("Path not found : " + srcAbsPath); 123 124 ItemLocation destLocation = new ItemLocation(destAbsPath, node.getName()); 125 126 WorkspaceContainer destContainer = ((RepositoryImpl)ticket.getRepository()).getContainer(destWorkspace); 127 128 log.debug("Clone "+node+" from "+serverContainer.getName()+" to "+destContainer.getName()); 129 130 if (destContainer.getNodeByPath(destLocation.getPath()) != null) 131 throw new ItemExistsException("Workspace.clone() failed: destination node'" + destAbsPath + 132 "'already exists in workspace : " + destWorkspace); 133 134 Node newParent = destContainer.getNodeByPath(new ItemLocation(destAbsPath).getPath()); 135 137 if (newParent == null) 138 throw new PathNotFoundException("Parent for '" + destAbsPath + "' not found."); 139 if (!newParent.getPrimaryNodeType().canAddChildNode(node.getName(), node.getPrimaryNodeType().getName())) 140 throw new ConstraintViolationException("Workspace.clone(): Adding node " + node + 141 " to " + newParent + " is not allowed!"); 142 143 List items = new ArrayList (); 144 if (shallow) 145 items.add(node); 146 else 147 getRecursively(node, items, serverContainer); 148 149 for (int i = 0; i < items.size(); i++) { 150 NodeImpl item = (NodeImpl) items.get(i); 151 String newPath = destAbsPath+item.getPath(); 152 NodeImpl newNode = new NodeImpl(newPath, item.getPermanentProperties()); 153 log.debug("Workspace.clone() new node = " + newNode); 154 destContainer.add(newNode); 155 156 Property uuid = newNode.getPermanentProperty("jcr:uuid"); 157 if (uuid != null) 158 getRepositoryManager().addLocation(destContainer.getName(), uuid.getString(), newNode.getPath(), true); 159 160 162 } 163 164 165 } 166 167 193 public void move(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, 194 AccessDeniedException, PathNotFoundException, ItemExistsException, 195 ActionVetoedException, RepositoryException { 196 copy(srcAbsPath, destAbsPath); 197 List items = new ArrayList (); 198 NodeImpl node = (NodeImpl)serverContainer.getNodeByPath(srcAbsPath); 199 getRecursively(node, items, serverContainer); 200 for(int i=0; i<items.size(); i++) { 201 NodeImpl childNode = (NodeImpl)items.get(i); 202 serverContainer.delete(childNode.getPath()); 204 Property uuid = childNode.getPermanentProperty("jcr:uuid"); 205 if (uuid != null) 206 getRepositoryManager().deleteLocationByUUID(serverContainer.getName(), uuid.getString()); 207 209 } 210 211 } 212 213 218 public QueryManager getQueryManager() { 219 QueryManagerImpl qm = QueryManagerImpl.getInstance(); 220 qm.init(this); 221 return qm; 222 } 223 224 230 public NodeTypeManager getNodeTypeManager() { 231 return NodeTypeManagerImpl.getInstance(); 232 } 233 234 235 241 public NamespaceRegistry getNamespaceRegistry() { 242 return (NamespaceRegistry) PortalContainer.getInstance(). 243 getComponentInstanceOfType(NamespaceRegistry.class); 244 } 245 246 265 public AccessManager getAccessManager() throws UnsupportedRepositoryOperationException { 266 throw new UnsupportedRepositoryOperationException("Workspace.getAccessManager() is not supported by Level 1 of JCR."); 267 } 268 269 270 292 public LockCapabilities getLockCapabilities() throws UnsupportedRepositoryOperationException { 293 throw new UnsupportedRepositoryOperationException("Workspace.getLockCapabilities() is not supported by Level 1 of JCR."); 294 } 295 296 317 public ObservationManager getObservationManager() throws UnsupportedRepositoryOperationException { 318 throw new UnsupportedRepositoryOperationException("Workspace.getObservationManager() is not supported by Level 1 of JCR."); 319 } 320 321 322 326 public void exportSysView(String absPath, ContentHandler handler, boolean binaryAsLink, boolean noRecurse) 327 throws PathNotFoundException, SAXException , RepositoryException { 328 NodeImpl node = (NodeImpl) serverContainer.getNodeByPath(absPath); 329 XMLWriter writer = new XMLWriter(((NamespaceRegistryImpl) getNamespaceRegistry()).getURIMap()); 330 initNodeAsSysView(node, writer, binaryAsLink, noRecurse); 331 332 invokeHandler(writer.getBytes(), handler); 333 } 334 335 339 public void exportSysView(String absPath, OutputStream out, boolean binaryAsLink, boolean noRecurse) 340 throws IOException , PathNotFoundException, RepositoryException { 341 NodeImpl node = (NodeImpl) serverContainer.getNodeByPath(absPath); 342 if (node == null) 343 throw new PathNotFoundException("exportSysView error: node not found at the path '" + absPath + "'"); 344 345 XMLWriter writer = new XMLWriter(((NamespaceRegistryImpl) getNamespaceRegistry()).getURIMap()); 346 initNodeAsSysView(node, writer, binaryAsLink, noRecurse); 347 348 try { 349 out.write(writer.getBytes()); 350 } catch (IOException e) { 351 throw new RepositoryException("Write Sys View failed. Reason: " + e); 352 } 353 354 } 355 356 360 public void exportDocView(String absPath, ContentHandler handler, boolean binaryAsLink, boolean noRecurse) 361 throws PathNotFoundException, SAXException , RepositoryException { 362 NodeImpl node = (NodeImpl) serverContainer.getNodeByPath(absPath); 363 XMLWriter writer = new XMLWriter(((NamespaceRegistryImpl) getNamespaceRegistry()).getURIMap()); 364 initNodeAsDocView(node, writer, binaryAsLink, noRecurse); 365 366 invokeHandler(writer.getBytes(), handler); 367 } 368 369 private void invokeHandler(byte[] input, ContentHandler contentHandler) 370 throws SAXException , RepositoryException { 371 try { 372 SAXParserFactory factory = SAXParserFactory.newInstance(); 373 SAXParser parser = factory.newSAXParser(); 374 XMLReader reader = parser.getXMLReader(); 375 reader.setContentHandler(contentHandler); 376 reader.parse(new InputSource (new ByteArrayInputStream (input))); 377 } catch (SAXException e) { 378 throw e; 379 } catch (Exception e) { 380 throw new RepositoryException("Can not invoke content handler", e); 381 } 382 } 383 384 388 public void exportDocView(String absPath, OutputStream out, boolean binaryAsLink, boolean noRecurse) 389 throws IOException , PathNotFoundException, RepositoryException { 390 NodeImpl node = (NodeImpl) serverContainer.getNodeByPath(absPath); 391 if (node == null) 392 throw new PathNotFoundException("exportDocView error: node not found at the path '" + absPath + "'"); 393 XMLWriter writer = new XMLWriter(((NamespaceRegistryImpl) getNamespaceRegistry()).getURIMap()); 394 initNodeAsDocView(node, writer, binaryAsLink, noRecurse); 395 396 try { 397 out.write(writer.getBytes()); 398 } catch (IOException e) { 399 throw new RepositoryException("Write Doc View failed. Reason: " + e); 400 } 401 402 } 403 404 405 public void copy(String srcPath, String destPath, boolean shallow) throws ItemExistsException, 406 AccessDeniedException, ConstraintViolationException, RepositoryException { 407 408 NodeImpl node = (NodeImpl) serverContainer.getNodeByPath(srcPath); 409 410 if (node == null) 411 throw new PathNotFoundException("Path not found : " + srcPath); 412 413 if (serverContainer.getNodeByPath(destPath) != null) 414 throw new ItemExistsException("Workspace.copy() failed: destination node'" + destPath + 415 "'already exists!"); 416 417 Node newParent = serverContainer.getNodeByPath(new ItemLocation(destPath).getAncestorPath(1)); 418 if (newParent == null) 419 throw new PathNotFoundException("Parent for '" + destPath + "' not found."); 420 if (!newParent.getPrimaryNodeType().canAddChildNode(node.getName(), node.getPrimaryNodeType().getName())) 421 throw new ConstraintViolationException("Workspace.copy(): Adding node " + node + " to " + newParent + " is not allowed!"); 422 423 List items = new ArrayList (); 424 if (shallow) 425 items.add(node); 426 else 427 getRecursively(node, items, serverContainer); 428 429 for (int i = 0; i < items.size(); i++) { 430 NodeImpl item = (NodeImpl) items.get(i); 431 String _path = PathUtil.rewriteSuffix(item.getPath(), srcPath, destPath); 433 List props = new ArrayList (); 434 Iterator propertyIterator = item.getPermanentProperties().iterator(); 435 436 while (propertyIterator.hasNext()) { 437 PropertyImpl property = (PropertyImpl) propertyIterator.next(); 438 String propPath = PathUtil.rewriteSuffix(property.getPath(), srcPath, destPath); 439 log.debug("Workspace.copy() new prop = " + propPath); 440 props.add(new PropertyImpl(propPath, property.getValue(), property.getType())); 441 } 442 443 NodeImpl newNode = new NodeImpl(_path, props); 444 log.debug("Workspace.copy() new node = " + newNode); 446 serverContainer.add(newNode); 447 } 448 449 } 450 451 452 456 public void copy(String srcPath, String destPath) throws ItemExistsException, AccessDeniedException, RepositoryException { 457 copy(srcPath, destPath, false); 458 } 459 460 461 463 private void getRecursively(NodeImpl node, List items, WorkspaceContainer c) { 464 log.debug("GET Recursively " + node); 465 items.add(node); 466 467 try { 468 469 List children = c.getChildren(node.getPath()); 470 for (int i = 0; i < children.size(); i++) { 471 String path = (String ) children.get(i); 472 NodeImpl item = (NodeImpl)c.getNodeByPath(path); 473 getRecursively(item, items, c); 474 } 475 } catch (RepositoryException e) { 476 e.printStackTrace(); 477 throw new RuntimeException ("NodesStorage.getRecursively() for "+node.getPath()+" FAILED "+e); 478 } 479 } 480 481 private void initNodeAsSysView(NodeImpl node, XMLWriter writer, boolean binaryAsLink, boolean noRecurse) 483 throws RepositoryException { 484 485 log.debug("Sys --" + node + " writer: " + writer); 486 487 String name = node.getName(); 488 489 if (name.length() == 0) name = "sv:root"; 491 492 Properties attrs = new Properties (); 493 attrs.setProperty("sv:name", name); 494 writer.startElement("sv:node", attrs); 495 496 PropertyIterator props = node.getProperties(); 497 while (props.hasNext()) { 498 PropertyImpl prop = (PropertyImpl) props.next(); 499 String strPropVal = getStrPropValue(prop, binaryAsLink); 500 String strPropType; 501 if (prop.getType() == PropertyType.BINARY && binaryAsLink) 502 strPropType = PropertyType.nameFromValue(PropertyType.SOFTLINK).toLowerCase(); 503 else 504 strPropType = PropertyType.nameFromValue(prop.getType()).toLowerCase(); 505 506 attrs = new Properties (); 507 attrs.setProperty("sv:name", prop.getName()); 508 attrs.setProperty("sv:type", "pt:" + strPropType); 509 writer.startElement("sv:property", attrs); 510 writer.writeText(strPropVal); 511 writer.endElement(); 512 } 513 514 List nodes = serverContainer.getChildren(node.getPath()); 515 for (int i = 0; i < nodes.size(); i++) { 516 String path = (String ) nodes.get(i); 518 NodeImpl child = (NodeImpl) serverContainer.getNodeByPath(path); 519 if (!noRecurse) 520 initNodeAsSysView(child, writer, binaryAsLink, noRecurse); 521 } 522 writer.endElement(); 523 } 524 525 private void initNodeAsDocView(NodeImpl node, XMLWriter writer, boolean binaryAsLink, boolean noRecurse) throws RepositoryException { 527 528 String name = node.getName(); 529 if (name.length() == 0) name = "root"; 531 532 Properties attrs = new Properties (); 534 535 PropertyIterator props = node.getProperties(); 536 while (props.hasNext()) { 537 PropertyImpl prop = (PropertyImpl) props.next(); 538 String strPropVal = getStrPropValue(prop, binaryAsLink); 539 attrs.setProperty(prop.getName(), strPropVal); 540 } 541 writer.startElement(name, attrs); 542 543 List nodes = serverContainer.getChildren(node.getPath()); 544 for (int i = 0; i < nodes.size(); i++) { 545 String path = (String ) nodes.get(i); 546 NodeImpl child = (NodeImpl) serverContainer.getNodeByPath(path); 547 if (!noRecurse) 549 initNodeAsDocView(child, writer, binaryAsLink, noRecurse); 550 } 551 552 writer.endElement(); 553 } 554 555 private String getStrPropValue(PropertyImpl prop, boolean binaryAsLink) { 556 if (prop.getType() == PropertyType.BINARY) { 557 if (binaryAsLink) 558 return prop.getPath(); 559 else { 560 String str = new String (Base64.encodeBase64(prop.getString().getBytes())); 561 return str; 562 } 563 } else 564 return StringConverter.normalizeString(prop.getString(), false); 565 } 566 567 568 public WorkspaceContainer getContainer() { 570 return serverContainer; 571 } 572 573 public String getWorkspaceName() { 574 return workspaceName; 575 } 576 577 private RepositoryManager getRepositoryManager() { 578 return ((RepositoryImpl)ticket.getRepository()).getRepositoryManager(); 579 } 580 581 } 582 | Popular Tags |