/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // COPIED FROM JACKRABBIT 2.4.0 (No additional NOTICE required, see VFS-611) package org.apache.commons.vfs2.provider.webdav4.test; import java.io.InputStream; import java.util.Calendar; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Value; /** * Collection of static utility methods for use with the JCR 1.0 API and Apache Jackrabbit 1.5.2. * * Copied, adapted and pruned down from Jackrabbit 2.4.0. * * @since 2.5.0 */ class JcrUtils { private static final String NodeType_NT_RESOURCE = "nt:resource"; private static final String Node_JCR_CONTENT = "jcr:content"; private static final String NodeType_NT_FOLDER = "nt:folder"; private static final String NodeType_NT_FILE = "nt:file"; private static final String Property_JCR_MIMETYPE = "jcr:mimeType"; private static final String Property_JCR_ENCODING = "jcr:encoding"; private static final String Property_JCR_LAST_MODIFIED = "jcr:lastModified"; private static final String Property_JCR_DATA = "jcr:data"; /** * Returns the named child of the given node, creating it as an nt:folder node if it does not already exist. The * caller is expected to take care of saving or discarding any transient changes. * <p> * Note that the type of the returned node is <em>not</em> guaranteed to match nt:folder in case the node already * existed. The caller can use an explicit {@link Node#isNodeType(String)} check if needed, or simply use a * data-first approach and not worry about the node type until a constraint violation is encountered. * * @param parent parent node * @param name name of the child node * @return the child node * @throws RepositoryException if the child node can not be accessed or created */ public static Node getOrAddFolder(final Node parent, final String name) throws RepositoryException { return getOrAddNode(parent, name, NodeType_NT_FOLDER); } /** * Returns the named child of the given node, creating the child if it does not already exist. If the child node * gets added, then it is created with the given node type. The caller is expected to take care of saving or * discarding any transient changes. * * @see Node#getNode(String) * @see Node#addNode(String, String) * @see Node#isNodeType(String) * @param parent parent node * @param name name of the child node * @param type type of the child node, ignored if the child already exists * @return the child node * @throws RepositoryException if the child node can not be accessed or created */ public static Node getOrAddNode(final Node parent, final String name, final String type) throws RepositoryException { if (parent.hasNode(name)) { return parent.getNode(name); } return parent.addNode(name, type); } /** * Creates or updates the named child of the given node. If the child does not already exist, then it is created * using the nt:file node type. This file child node is returned from this method. * <p> * If the file node does not already contain a jcr:content child, then one is created using the nt:resource node * type. The following properties are set on the jcr:content node: * <dl> * <dt>jcr:mimeType</dt> * <dd>media type</dd> * <dt>jcr:encoding (optional)</dt> * <dd>charset parameter of the media type, if any</dd> * <dt>jcr:lastModified</dt> * <dd>current time</dd> * <dt>jcr:data</dt> * <dd>binary content</dd> * </dl> * <p> * Note that the types of the returned node or the jcr:content child are <em>not</em> guaranteed to match nt:file * and nt:resource in case the nodes already existed. The caller can use an explicit {@link Node#isNodeType(String)} * check if needed, or simply use a data-first approach and not worry about the node type until a constraint * violation is encountered. * <p> * The given binary content stream is closed by this method. * * @param parent parent node * @param name name of the file * @param mime media type of the file * @param data binary content of the file * @return the child node * @throws RepositoryException if the child node can not be created or updated */ public static Node putFile(final Node parent, final String name, final String mime, final InputStream data) throws RepositoryException { return putFile(parent, name, mime, data, Calendar.getInstance()); } /** * Creates or updates the named child of the given node. If the child does not already exist, then it is created * using the nt:file node type. This file child node is returned from this method. * <p> * If the file node does not already contain a jcr:content child, then one is created using the nt:resource node * type. The following properties are set on the jcr:content node: * <dl> * <dt>jcr:mimeType</dt> * <dd>media type</dd> * <dt>jcr:encoding (optional)</dt> * <dd>charset parameter of the media type, if any</dd> * <dt>jcr:lastModified</dt> * <dd>date of last modification</dd> * <dt>jcr:data</dt> * <dd>binary content</dd> * </dl> * <p> * Note that the types of the returned node or the jcr:content child are <em>not</em> guaranteed to match nt:file * and nt:resource in case the nodes already existed. The caller can use an explicit {@link Node#isNodeType(String)} * check if needed, or simply use a data-first approach and not worry about the node type until a constraint * violation is encountered. * <p> * The given binary content stream is closed by this method. * * @param parent parent node * @param name name of the file * @param mime media type of the file * @param data binary content of the file * @param date date of last modification * @return the child node * @throws RepositoryException if the child node can not be created or updated */ public static Node putFile(final Node parent, final String name, final String mime, final InputStream data, final Calendar date) throws RepositoryException { final Value binary = parent.getSession().getValueFactory().createValue(data); try { final Node file = getOrAddNode(parent, name, NodeType_NT_FILE); final Node content = getOrAddNode(file, Node_JCR_CONTENT, NodeType_NT_RESOURCE); content.setProperty(Property_JCR_MIMETYPE, mime); final String[] parameters = mime.split(";"); for (int i = 1; i < parameters.length; i++) { final int equals = parameters[i].indexOf('='); if (equals != -1) { final String parameter = parameters[i].substring(0, equals); if ("charset".equalsIgnoreCase(parameter.trim())) { content.setProperty(Property_JCR_ENCODING, parameters[i].substring(equals + 1).trim()); } } } content.setProperty(Property_JCR_LAST_MODIFIED, date); content.setProperty(Property_JCR_DATA, binary); return file; } finally { // JCR 2.0 API: // binary.dispose(); } } /** * Private constructor to prevent instantiation of this class. */ private JcrUtils() { } }