1 17 package org.alfresco.jcr.importer; 18 19 import java.io.File ; 20 import java.io.FileInputStream ; 21 import java.io.FileNotFoundException ; 22 import java.io.InputStream ; 23 import java.io.Serializable ; 24 import java.util.List ; 25 import java.util.Stack ; 26 27 import javax.jcr.InvalidSerializedDataException; 28 import javax.jcr.PropertyType; 29 import javax.jcr.RepositoryException; 30 31 import org.alfresco.jcr.dictionary.DataTypeMap; 32 import org.alfresco.jcr.dictionary.JCRNamespace; 33 import org.alfresco.jcr.exporter.JCRSystemXMLExporter; 34 import org.alfresco.jcr.item.property.JCRMixinTypesProperty; 35 import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty; 36 import org.alfresco.jcr.item.property.JCRUUIDProperty; 37 import org.alfresco.jcr.session.SessionImpl; 38 import org.alfresco.repo.importer.ImportContentHandler; 39 import org.alfresco.repo.importer.Importer; 40 import org.alfresco.repo.importer.view.ElementContext; 41 import org.alfresco.repo.importer.view.NodeContext; 42 import org.alfresco.repo.importer.view.ParentContext; 43 import org.alfresco.service.cmr.dictionary.AspectDefinition; 44 import org.alfresco.service.cmr.dictionary.DataTypeDefinition; 45 import org.alfresco.service.cmr.dictionary.InvalidTypeException; 46 import org.alfresco.service.cmr.dictionary.TypeDefinition; 47 import org.alfresco.service.cmr.repository.NodeRef; 48 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter; 49 import org.alfresco.service.cmr.view.ImporterException; 50 import org.alfresco.service.namespace.NamespacePrefixResolver; 51 import org.alfresco.service.namespace.QName; 52 import org.alfresco.util.Base64; 53 import org.xml.sax.Attributes ; 54 import org.xml.sax.Locator ; 55 import org.xml.sax.SAXException ; 56 import org.xml.sax.SAXParseException ; 57 58 59 64 public class JCRSystemXMLHandler implements ImportContentHandler 65 { 66 private Importer importer; 67 private SessionImpl session; 68 private NamespacePrefixResolver importResolver; 69 private Stack <ElementContext> contextStack = new Stack <ElementContext>(); 70 71 72 78 public JCRSystemXMLHandler(SessionImpl session, NamespacePrefixResolver importResolver) 79 { 80 this.session = session; 81 this.importResolver = importResolver; 82 } 83 84 88 public void setImporter(Importer importer) 89 { 90 this.importer = importer; 91 } 92 93 97 public InputStream importStream(String content) 98 { 99 File contentFile = new File (content); 100 try 101 { 102 FileInputStream contentStream = new FileInputStream (contentFile); 103 return new Base64.InputStream(contentStream, Base64.DECODE | Base64.DONT_BREAK_LINES); 104 } 105 catch (FileNotFoundException e) 106 { 107 throw new ImporterException("Failed to retrieve import input stream on temporary content file " + content); 108 } 109 } 110 111 115 public void setDocumentLocator(Locator locator) 116 { 117 } 119 120 124 public void startDocument() throws SAXException 125 { 126 } 128 129 133 public void endDocument() throws SAXException 134 { 135 } 137 138 142 public void startPrefixMapping(String prefix, String uri) throws SAXException 143 { 144 } 146 147 151 public void endPrefixMapping(String prefix) throws SAXException 152 { 153 } 155 156 160 public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException 161 { 162 try 163 { 164 QName elementName = QName.createQName(qName, importResolver); 166 167 if (JCRSystemXMLExporter.NODE_QNAME.equals(elementName)) 168 { 169 processStartNode(elementName, atts); 170 } 171 else if (JCRSystemXMLExporter.PROPERTY_QNAME.equals(elementName)) 172 { 173 processStartProperty(elementName, atts); 174 } 175 else if (JCRSystemXMLExporter.VALUE_QNAME.equals(elementName)) 176 { 177 processStartValue(elementName, atts); 178 } 179 } 180 catch(Exception e) 181 { 182 throw new SAXException ("Failed to process element " + qName, e); 183 } 184 } 185 186 193 private void processStartNode(QName elementName, Attributes atts) 194 throws InvalidSerializedDataException 195 { 196 ParentContext parentContext = null; 197 if (contextStack.empty()) 198 { 199 parentContext = new ParentContext(elementName, session.getRepositoryImpl().getServiceRegistry().getDictionaryService(), importer); 201 } 202 else 203 { 204 NodeContext parentNode = (NodeContext)contextStack.peek(); 205 206 if (parentNode.getNodeRef() == null) 208 { 209 NodeRef nodeRef = importer.importNode(parentNode); 210 parentNode.setNodeRef(nodeRef); 211 } 212 213 parentContext = new ParentContext(elementName, parentNode); 215 } 216 217 NodeContext nodeContext = new NodeContext(elementName, parentContext, null); 220 221 String name = atts.getValue(JCRSystemXMLExporter.NAME_QNAME.toPrefixString(importResolver)); 223 if (name == null) 224 { 225 throw new InvalidSerializedDataException("Mandatory sv:name attribute of element sv:node not present."); 226 } 227 nodeContext.setChildName(name); 228 229 contextStack.push(nodeContext); 231 } 232 233 240 private void processStartProperty(QName elementName, Attributes atts) 241 throws InvalidSerializedDataException 242 { 243 ElementContext context = contextStack.peek(); 245 if (!(context instanceof NodeContext)) 246 { 247 throw new InvalidSerializedDataException("Element " + elementName + " not expected."); 248 } 249 NodeContext parentNode = (NodeContext)context; 250 251 String name = atts.getValue(JCRSystemXMLExporter.NAME_QNAME.toPrefixString(importResolver)); 253 if (name == null) 254 { 255 throw new InvalidSerializedDataException("Mandatory sv:name attribute of element sv:node not present."); 256 } 257 QName propertyName = QName.createQName(name, importResolver); 258 259 QName dataType = null; 261 String type = atts.getValue(JCRSystemXMLExporter.TYPE_QNAME.toPrefixString(importResolver)); 262 if (type == null) 263 { 264 throw new InvalidSerializedDataException("Mandatory sv:type attribute of element sv:node not present."); 265 } 266 try 267 { 268 dataType = DataTypeMap.convertPropertyTypeToDataType(PropertyType.valueFromName(type)); 269 } 270 catch(IllegalArgumentException e) 271 { 272 throw new ImporterException("Type " + type + " is not known for property " + name); 273 } 274 275 PropertyContext propertyContext = new PropertyContext(elementName, parentNode, propertyName, dataType); 277 contextStack.push(propertyContext); 278 } 279 280 287 private void processStartValue(QName elementName, Attributes atts) 288 throws InvalidSerializedDataException 289 { 290 ElementContext context = contextStack.peek(); 292 if (!(context instanceof PropertyContext)) 293 { 294 throw new InvalidSerializedDataException("Element " + elementName + " not expected."); 295 } 296 PropertyContext property = (PropertyContext)context; 297 property.startValue(); 298 299 ValueContext value = new ValueContext(elementName, property); 300 contextStack.push(value); 301 } 302 303 307 public void endElement(String uri, String localName, String qName) throws SAXException 308 { 309 try 310 { 311 ElementContext context = (ElementContext)contextStack.peek(); 313 QName elementName = QName.createQName(qName, importResolver); 314 if (!context.getElementName().equals(elementName)) 315 { 316 throw new InvalidSerializedDataException("Expected element " + context.getElementName() + " but was " + elementName); 317 } 318 319 if (JCRSystemXMLExporter.NODE_QNAME.equals(elementName)) 320 { 321 processEndNode((NodeContext)context); 322 } 323 else if (JCRSystemXMLExporter.PROPERTY_QNAME.equals(elementName)) 324 { 325 processEndProperty((PropertyContext)context); 326 } 327 else if (JCRSystemXMLExporter.VALUE_QNAME.equals(elementName)) 328 { 329 processEndValue((ValueContext)context); 330 } 331 332 contextStack.pop(); 334 } 335 catch(Exception e) 336 { 337 throw new SAXException ("Failed to process element " + qName, e); 338 } 339 } 340 341 346 private void processEndNode(NodeContext node) 347 { 348 NodeRef nodeRef = node.getNodeRef(); 350 if (nodeRef == null) 351 { 352 nodeRef = node.getImporter().importNode(node); 353 node.setNodeRef(nodeRef); 354 } 355 356 node.getImporter().childrenImported(nodeRef); 358 } 359 360 367 private void processEndProperty(PropertyContext context) 368 throws InvalidSerializedDataException, RepositoryException 369 { 370 QName propertyName = context.getName(); 371 372 if (context.isNull()) 374 { 375 throw new InvalidSerializedDataException("Property " + propertyName + " must have a value"); 376 } 377 378 382 if (JCRPrimaryTypeProperty.PROPERTY_NAME.equals(propertyName)) 383 { 384 if (!context.isNull()) 386 { 387 QName typeQName = QName.createQName(context.getValues().get(0).toString(), importResolver); 388 TypeDefinition typeDef = context.getDictionaryService().getType(typeQName); 389 if (typeDef == null) 390 { 391 throw new InvalidTypeException(typeQName); 392 } 393 394 context.getNode().setTypeDefinition(typeDef); 396 } 397 } 398 else if (JCRMixinTypesProperty.PROPERTY_NAME.equals(propertyName)) 399 { 400 List <StringBuffer > values = context.getValues(); 402 for (StringBuffer value : values) 403 { 404 QName aspectQName = QName.createQName(value.toString(), importResolver); 405 406 if (!(JCRNamespace.JCR_URI.equals(aspectQName.getNamespaceURI()) || 408 JCRNamespace.MIX_URI.equals(aspectQName.getNamespaceURI()))) 409 { 410 AspectDefinition aspectDef = context.getDictionaryService().getAspect(aspectQName); 411 if (aspectDef == null) 412 { 413 throw new InvalidTypeException(aspectQName); 414 } 415 context.getNode().addAspect(aspectDef); 416 } 417 } 418 } 419 else if (JCRUUIDProperty.PROPERTY_NAME.equals(propertyName)) 420 { 421 StringBuffer value = context.getValues().get(0); 422 context.getNode().setUUID(value.toString()); 423 } 424 425 429 else if (JCRNamespace.JCR_URI.equals(propertyName.getNamespaceURI())) 430 { 431 } 432 433 437 else 438 { 439 NodeContext node = context.getNode(); 441 if (node.getTypeDefinition() == null) 442 { 443 throw new InvalidSerializedDataException("Node jcr:primaryType property has not been specified."); 444 } 445 446 QName dataType = context.getType(); 448 DataTypeDefinition dataTypeDef = context.getDictionaryService().getDataType(dataType); 449 if (dataTypeDef == null) 450 { 451 throw new InvalidTypeException(dataType); 452 } 453 node.addDatatype(propertyName, dataTypeDef); 454 455 if (context.isMultiValue()) 457 { 458 node.addPropertyCollection(propertyName); 459 } 460 461 List <StringBuffer > values = context.getValues(); 463 for (StringBuffer value : values) 464 { 465 Serializable objVal = (Serializable )session.getTypeConverter().convert(dataTypeDef, value.toString()); 467 String strValue = DefaultTypeConverter.INSTANCE.convert(String .class, objVal); 468 node.addProperty(propertyName, strValue); 469 } 470 } 471 } 472 473 478 private void processEndValue(ValueContext context) 479 { 480 PropertyContext property = context.getProperty(); 481 property.endValue(); 482 } 483 484 488 public void characters(char[] ch, int start, int length) throws SAXException 489 { 490 ElementContext context = (ElementContext)contextStack.peek(); 491 if (context instanceof ValueContext) 492 { 493 PropertyContext property = ((ValueContext)context).getProperty(); 494 property.appendCharacters(ch, start, length); 495 } 496 } 497 498 502 public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException 503 { 504 ElementContext context = (ElementContext)contextStack.peek(); 505 if (context instanceof ValueContext) 506 { 507 PropertyContext property = ((ValueContext)context).getProperty(); 508 property.appendCharacters(ch, start, length); 509 } 510 } 511 512 516 public void processingInstruction(String target, String data) throws SAXException 517 { 518 } 519 520 524 public void skippedEntity(String name) throws SAXException 525 { 526 } 527 528 532 public void warning(SAXParseException exception) throws SAXException 533 { 534 } 535 536 540 public void error(SAXParseException exception) throws SAXException 541 { 542 } 543 544 548 public void fatalError(SAXParseException exception) throws SAXException 549 { 550 } 551 552 } 553 | Popular Tags |