📄 defaulthandler.java
字号:
} /** * Retrieves the content node that will be used for exporting properties and * data and calls the corresponding methods. * * @param context * @param isCollection * @see #exportProperties(ExportContext, boolean, Node) * @see #exportData(ExportContext, boolean, Node) */ public boolean exportContent(ExportContext context, boolean isCollection) throws IOException { if (!canExport(context, isCollection)) { throw new IOException(getName() + ": Cannot export " + context.getExportRoot()); } try { Node contentNode = getContentNode(context, isCollection); exportProperties(context, isCollection, contentNode); if (context.hasStream()) { exportData(context, isCollection, contentNode); } // else: missing stream. ignore. return true; } catch (RepositoryException e) { // should never occur, since the proper structure of the content // node must be asserted in the 'canExport' call. throw new IOException(e.getMessage()); } } /** * Same as (@link IOHandler#exportContent(ExportContext, boolean)} where * the boolean values is defined by {@link DavResource#isCollection()}. * * @see IOHandler#exportContent(ExportContext, DavResource) */ public boolean exportContent(ExportContext context, DavResource resource) throws IOException { if (!canExport(context, resource)) { throw new IOException(getName() + ": Cannot export " + context.getExportRoot()); } return exportContent(context, resource.isCollection()); } /** * Checks if the given content node contains a jcr:data property * and spools its value to the output stream fo the export context.<br> * Please note, that subclasses that define a different structure of the * content node should create their own * {@link #exportData(ExportContext, boolean, Node) exportData} method. * * @param context * @param isCollection * @param contentNode * @throws IOException */ protected void exportData(ExportContext context, boolean isCollection, Node contentNode) throws IOException, RepositoryException { if (contentNode.hasProperty(JcrConstants.JCR_DATA)) { Property p = contentNode.getProperty(JcrConstants.JCR_DATA); IOUtil.spool(p.getStream(), context.getOutputStream()); } // else: stream undefined -> contentlength was not set } /** * Retrieves mimetype, encoding and modification time from the content node. * The content length is determined by the length of the jcr:data property * if it is present. The creation time however is retrieved from the parent * node (in case of isCollection == false only). * * @param context * @param isCollection * @param contentNode */ protected void exportProperties(ExportContext context, boolean isCollection, Node contentNode) throws IOException { try { // only non-collections: 'jcr:created' is present on the parent 'fileNode' only if (!isCollection && contentNode.getDepth() > 0 && contentNode.getParent().hasProperty(JcrConstants.JCR_CREATED)) { long cTime = contentNode.getParent().getProperty(JcrConstants.JCR_CREATED).getValue().getLong(); context.setCreationTime(cTime); } long length = IOUtil.UNDEFINED_LENGTH; if (contentNode.hasProperty(JcrConstants.JCR_DATA)) { Property p = contentNode.getProperty(JcrConstants.JCR_DATA); length = p.getLength(); context.setContentLength(length); } String mimeType = null; String encoding = null; if (contentNode.hasProperty(JcrConstants.JCR_MIMETYPE)) { mimeType = contentNode.getProperty(JcrConstants.JCR_MIMETYPE).getString(); } if (contentNode.hasProperty(JcrConstants.JCR_ENCODING)) { encoding = contentNode.getProperty(JcrConstants.JCR_ENCODING).getString(); // ignore "" encodings (although this is avoided during import) if ("".equals(encoding)) { encoding = null; } } context.setContentType(mimeType, encoding); long modTime = IOUtil.UNDEFINED_TIME; if (contentNode.hasProperty(JcrConstants.JCR_LASTMODIFIED)) { modTime = contentNode.getProperty(JcrConstants.JCR_LASTMODIFIED).getLong(); context.setModificationTime(modTime); } else { context.setModificationTime(System.currentTimeMillis()); } if (length > IOUtil.UNDEFINED_LENGTH && modTime > IOUtil.UNDEFINED_TIME) { String etag = "\"" + length + "-" + modTime + "\""; context.setETag(etag); } } catch (RepositoryException e) { // should never occur log.error("Unexpected error {0} while exporting properties: {1}", e.getClass().getName(), e.getMessage()); throw new IOException(e.getMessage()); } } /** * Retrieves the content node that contains the data to be exported. In case * isCollection is true, this corresponds to the export root. Otherwise there * must be a child node with name {@link JcrConstants#JCR_CONTENT jcr:content}. * * @param context * @param isCollection * @return content node used for the export * @throws RepositoryException */ protected Node getContentNode(ExportContext context, boolean isCollection) throws RepositoryException { Node contentNode = (Node)context.getExportRoot(); // 'file' nodes must have an jcr:content child node (see canExport) if (!isCollection) { contentNode = contentNode.getNode(JcrConstants.JCR_CONTENT); } return contentNode; } /** * Name of the nodetype to be used to create a new collection node (folder) * * @return nodetype name */ protected String getCollectionNodeType() { return collectionNodetype; } /** * Name of the nodetype to be used to create a new non-collection node (file) * * @return nodetype name */ protected String getNodeType() { return defaultNodetype; } /** * Name of the nodetype to be used to create the content node below * a new non-collection node, whose name is always {@link JcrConstants#JCR_CONTENT * jcr:content}. * * @return nodetype name */ protected String getContentNodeType() { return contentNodetype; } //----------------------------------------------------< PropertyHandler >--- public boolean canExport(PropertyExportContext context, boolean isCollection) { return canExport((ExportContext) context, isCollection); } public boolean exportProperties(PropertyExportContext exportContext, boolean isCollection) throws RepositoryException { if (!canExport(exportContext, isCollection)) { throw new RepositoryException("PropertyHandler " + getName() + " failed to export properties."); } Node cn = getContentNode(exportContext, isCollection); try { // export the properties common with normal IO handling exportProperties(exportContext, isCollection, cn); // export all other properties as well PropertyIterator it = cn.getProperties(); while (it.hasNext()) { Property p = it.nextProperty(); String name = p.getName(); PropertyDefinition def = p.getDefinition(); if (def.isMultiple()) { log.debug("Multivalued property '" + name + "' not added to webdav property set."); continue; } if (JcrConstants.JCR_DATA.equals(name) || JcrConstants.JCR_MIMETYPE.equals(name) || JcrConstants.JCR_ENCODING.equals(name) || JcrConstants.JCR_LASTMODIFIED.equals(name)) { continue; } DavPropertyName davName = getDavName(name, p.getSession()); exportContext.setProperty(davName, p.getValue().getString()); } return true; } catch (IOException e) { // should not occur (log output see 'exportProperties') return false; } } public boolean canImport(PropertyImportContext context, boolean isCollection) { if (context == null || context.isCompleted()) { return false; } Item contextItem = context.getImportRoot(); try { return contextItem != null && contextItem.isNode() && (isCollection || ((Node)contextItem).hasNode(JcrConstants.JCR_CONTENT)); } catch (RepositoryException e) { log.error("Unexpected error: " + e.getMessage()); return false; } } public Map importProperties(PropertyImportContext importContext, boolean isCollection) throws RepositoryException { if (!canImport(importContext, isCollection)) { throw new RepositoryException("PropertyHandler " + getName() + " failed import properties"); } // loop over List and remember all properties and propertyNames // that failed to be imported (set or remove). Map failures = new HashMap(); List changeList = importContext.getChangeList(); // for collections the import-root is the target node where properties // are altered. in contrast 'non-collections' are with the handler // represented by 'file' nodes, that must have a jcr:content child // node, which holds all properties except jcr:created. // -> see canImport for the corresponding assertions Node cn = (Node) importContext.getImportRoot(); if (!isCollection && cn.hasNode(JcrConstants.JCR_CONTENT)) { cn = cn.getNode(JcrConstants.JCR_CONTENT); } if (changeList != null) { Iterator it = changeList.iterator(); while (it.hasNext()) { Object propEntry = it.next(); try { if (propEntry instanceof DavPropertyName) { // remove DavPropertyName propName = (DavPropertyName)propEntry; removeJcrProperty(propName, cn); } else if (propEntry instanceof DavProperty) { // add or modify property DavProperty prop = (DavProperty)propEntry; setJcrProperty(prop, cn); } else { // ignore any other entry in the change list log.error("unknown object in change list: " + propEntry.getClass().getName()); } } catch (RepositoryException e) { failures.put(propEntry, e); } } } return failures; } //------------------------------------------------------------< private >--- /** * Builds a webdav property name from the given jcrName. In case the jcrName * contains a namespace prefix that would conflict with any of the predefined * webdav namespaces a new prefix is assigned.<br> * Please note, that the local part of the jcrName is checked for XML * compatibility by calling {@link ISO9075#encode(String)} * * @param jcrName * @param session * @return a <code>DavPropertyName</code> for the given jcr name. */ private DavPropertyName getDavName(String jcrName, Session session) throws RepositoryException { // make sure the local name is xml compliant String localName = ISO9075.encode(Text.getLocalName(jcrName)); String prefix = Text.getNamespacePrefix(jcrName); String uri = session.getNamespaceURI(prefix); Namespace namespace = Namespace.getNamespace(prefix, uri); DavPropertyName name = DavPropertyName.create(localName, namespace); return name; } /** * Build jcr property name from dav property name. If the property name * defines a namespace uri, that has not been registered yet, an attempt * is made to register the uri with the prefix defined. Note, that no * extra effort is made to generated a unique prefix. * * @param propName * @return jcr name * @throws RepositoryException */ private String getJcrName(DavPropertyName propName, Session session) throws RepositoryException { // remove any encoding necessary for xml compliance String pName = ISO9075.decode(propName.getName()); Namespace propNamespace = propName.getNamespace(); if (!Namespace.EMPTY_NAMESPACE.equals(propNamespace)) { String prefix; String emptyPrefix = Namespace.EMPTY_NAMESPACE.getPrefix(); try { // lookup 'prefix' in the session-ns-mappings / namespace-registry prefix = session.getNamespacePrefix(propNamespace.getURI()); } catch (NamespaceException e) { // namespace uri has not been registered yet NamespaceRegistry nsReg = session.getWorkspace().getNamespaceRegistry(); prefix = propNamespace.getPrefix(); // avoid trouble with default namespace if (emptyPrefix.equals(prefix)) { prefix = "_pre" + nsReg.getPrefixes().length + 1; } // NOTE: will fail if prefix is already in use in the namespace registry nsReg.registerNamespace(prefix, propNamespace.getURI()); } if (prefix != null && !emptyPrefix.equals(prefix)) { pName = prefix + ":" + pName; } } return pName; } /** * @param property * @throws RepositoryException */ private void setJcrProperty(DavProperty property, Node contentNode) throws RepositoryException { // Retrieve the property value. Note, that a 'null' value is replaced // by empty string, since setting a jcr property value to 'null' // would be equivalent to its removal. String value = ""; if (property.getValue() != null) { value = property.getValue().toString(); } contentNode.setProperty(getJcrName(property.getName(), contentNode.getSession()), value); } /** * @param propertyName * @throws RepositoryException */ private void removeJcrProperty(DavPropertyName propertyName, Node contentNode) throws RepositoryException { String jcrName = getJcrName(propertyName, contentNode.getSession()); if (contentNode.hasProperty(jcrName)) { contentNode.getProperty(jcrName).remove(); } // removal of non existing property succeeds }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -