| /* |
| * Copyright 2004-2005 The Apache Software Foundation or its licensors, |
| * as applicable. |
| * |
| * Licensed 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. |
| */ |
| package org.apache.jackrabbit.command; |
| |
| import java.io.PrintWriter; |
| import java.util.Iterator; |
| import java.util.ResourceBundle; |
| |
| import javax.jcr.Item; |
| import javax.jcr.Node; |
| import javax.jcr.NodeIterator; |
| import javax.jcr.PathNotFoundException; |
| import javax.jcr.PropertyIterator; |
| import javax.jcr.Repository; |
| import javax.jcr.RepositoryException; |
| import javax.jcr.Session; |
| |
| import org.apache.commons.chain.Context; |
| import org.apache.commons.collections.IteratorUtils; |
| |
| /** |
| * Utility class for getting and setting context attributes. |
| */ |
| public final class CommandHelper { |
| /** bundle */ |
| private static ResourceBundle bundle = ResourceBundle |
| .getBundle(CommandHelper.class.getPackage().getName() + ".resources"); |
| |
| /** Current node key */ |
| private static final String CURRENT_NODE_KEY = "jcr.current"; |
| |
| /** repository key */ |
| private static final String REPOSITORY_KEY = "jcr.repository"; |
| |
| /** session key */ |
| private static final String SESSION_KEY = "jcr.session"; |
| |
| /** session key */ |
| private static final String OUTPUT_KEY = "jcr.output"; |
| |
| /** |
| * should never get called |
| */ |
| private CommandHelper() { |
| super(); |
| } |
| |
| /** |
| * Sets the current <code>PrintWriter</code>. |
| * @param ctx |
| * the <code>Context</code> |
| * @param out |
| * the <code>PrintWriter</code> |
| */ |
| public static void setOutput(Context ctx, PrintWriter out) { |
| if (out == null) { |
| ctx.remove(OUTPUT_KEY); |
| } else { |
| ctx.put(OUTPUT_KEY, out); |
| } |
| } |
| |
| /** |
| * Sets the current working <code>Node</code>. |
| * @param ctx |
| * the <code>Context</code> |
| * @param node |
| * the current working <code>Node</code>. |
| */ |
| public static void setCurrentNode(Context ctx, Node node) { |
| if (node == null) { |
| ctx.remove(CURRENT_NODE_KEY); |
| } else { |
| ctx.put(CURRENT_NODE_KEY, node); |
| } |
| } |
| |
| /** |
| * Sets the current working <code>Repository</code> |
| * @param ctx |
| * the <code>Context</code> |
| * @param repository |
| * the current working <code>Repository</code> |
| */ |
| public static void setRepository(Context ctx, Repository repository) { |
| if (repository == null) { |
| ctx.remove(REPOSITORY_KEY); |
| } else { |
| ctx.put(REPOSITORY_KEY, repository); |
| } |
| } |
| |
| /** |
| * Sets the current working <code>Session</code> |
| * @param ctx |
| * the <code>Context</code> |
| * @param session |
| * the current working <code>Session</code> |
| * @throws CommandException if there's an open working <code>Session</code> |
| */ |
| public static void setSession(Context ctx, Session session) throws CommandException { |
| if (session == null) { |
| ctx.remove(SESSION_KEY); |
| } else { |
| if (ctx.get(SESSION_KEY) != null) { |
| throw new CommandException("exception.already.logged.in"); |
| } |
| ctx.put(SESSION_KEY, session); |
| } |
| } |
| |
| /** |
| * Gets the current <code>PrintWriter</code> |
| * @param ctx |
| * the <code>Context</code> |
| * @return the current <code>PrintWriter</code> |
| */ |
| public static PrintWriter getOutput(Context ctx) { |
| PrintWriter out = (PrintWriter) ctx.get(OUTPUT_KEY); |
| if (out == null) { |
| out = new PrintWriter(System.out, true); |
| } |
| return out; |
| } |
| |
| /** |
| * Gets the current working <code>Node</code> |
| * @param ctx |
| * the <code>Context</code> |
| * @return the current working <code>Node</code> |
| * @throws CommandException |
| * if the current working <code>Node</code> can't be found. |
| */ |
| public static Node getCurrentNode(Context ctx) throws CommandException { |
| Node n = (Node) ctx.get(CURRENT_NODE_KEY); |
| if (n == null) { |
| throw new CommandException("exception.no.current.node"); |
| } |
| return n; |
| } |
| |
| /** |
| * Gets the current working <code>Repository</code> |
| * @param ctx |
| * the <code>Context</code> |
| * @return the current working <code>Repository</code> |
| * @throws CommandException |
| * if the current working <code>Repository</code> is unset. |
| */ |
| public static Repository getRepository(Context ctx) throws CommandException { |
| Repository r = (Repository) ctx.get(REPOSITORY_KEY); |
| if (r == null) { |
| throw new CommandException("exception.no.current.repository"); |
| } |
| return r; |
| } |
| |
| /** |
| * Gets the current working <code>Session</code> |
| * @param ctx |
| * the <code>Context</code> |
| * @return the current working <code>Session</code> |
| * @throws CommandException |
| * if the current working <code>Session</code> is unset. |
| */ |
| public static Session getSession(Context ctx) throws CommandException { |
| Session s = (Session) ctx.get(SESSION_KEY); |
| if (s == null) { |
| throw new CommandException("exception.no.current.session"); |
| } |
| return s; |
| } |
| |
| /** |
| * Gets the <code>Node</code> at the given path. |
| * @param ctx |
| * the <code>Context</code> |
| * @param path |
| * the path to the <code>Node</code> |
| * @return the <code>Node</code> at the given path |
| * @throws CommandException |
| * if the <code>Node</code> isn't found. |
| * @throws RepositoryException |
| * if the underlying repository throws a |
| * <code>RepositoryException</code> |
| */ |
| public static Node getNode(Context ctx, String path) |
| throws CommandException, RepositoryException { |
| try { |
| Item i = getItem(ctx, path); |
| if (!i.isNode()) { |
| throw new CommandException("exception.no.node.at", |
| new String[] { |
| path |
| }); |
| } |
| return (Node) i; |
| } catch (PathNotFoundException e) { |
| throw new CommandException("exception.no.node.at", new String[] { |
| path |
| }); |
| } |
| } |
| |
| /** |
| * Gets the <code>Item</code> at the given path. <br> |
| * If the path is null it returns the current working <code>Node</code>. |
| * @param ctx |
| * the <code>Context</code> |
| * @param path |
| * the path to the <code>Item</code> |
| * @return the <code>Item</code> at the given path |
| * @throws CommandException |
| * if a <code>Command</code> internal error occurs. |
| * @throws PathNotFoundException |
| * if there's no <code>Node</code> at the given path. |
| * @throws RepositoryException |
| * if the underlying repository throws a |
| * <code>RepositoryException</code> |
| */ |
| public static Item getItem(Context ctx, String path) |
| throws CommandException, PathNotFoundException, RepositoryException { |
| Node current = getCurrentNode(ctx); |
| Item i = null; |
| |
| if (path == null) { |
| i = current; |
| } else if (path.equals("/")) { |
| i = current.getSession().getRootNode(); |
| } else if (path.startsWith("/")) { |
| i = current.getSession().getItem(path); |
| } else { |
| String newPath = current.getPath(); |
| // handle the root node |
| if (!newPath.endsWith("/")) { |
| newPath += "/"; |
| } |
| newPath += path; |
| i = current.getSession().getItem(newPath); |
| } |
| |
| return i; |
| } |
| |
| /** |
| * Checks <code>Node</code> existence. |
| * @param ctx |
| * the <code>Context</code> |
| * @param path |
| * the path to the <code>Node</code> |
| * @return true if the <code>Node</code> exists at the given path |
| * @throws CommandException |
| * if the current working <code>Session</code> is unset. |
| * @throws RepositoryException |
| * if the underlying repository throws a |
| * <code>RepositoryException</code> |
| */ |
| public static boolean hasNode(Context ctx, String path) |
| throws CommandException, RepositoryException { |
| Session s = getSession(ctx); |
| if (path.equals("/")) { |
| return true; |
| } else if (path.startsWith("/")) { |
| return s.getRootNode().hasNode(path.substring(1)); |
| } else { |
| Node current = (Node) ctx.get(CURRENT_NODE_KEY); |
| return current.hasNode(path); |
| } |
| } |
| |
| /** |
| * Gets the <code>Node</code> s under the given <code>Node</code> that |
| * match the given pattern. |
| * @param ctx |
| * the <code>Context</code> |
| * @param node |
| * the parent <code>Node</code> |
| * @param pattern |
| * the pattern |
| * @return an <code>Iterator</code> that contains the matching nodes |
| * @throws RepositoryException |
| * if the underlying repository throws a |
| * <code>RepositoryException</code> |
| */ |
| public static NodeIterator getNodes(Context ctx, Node node, String pattern) |
| throws RepositoryException { |
| if (pattern != null) { |
| return node.getNodes(pattern); |
| } else { |
| return node.getNodes(); |
| } |
| } |
| |
| /** |
| * Gets the <code>Property</code> s under the current working node for the |
| * given pattern |
| * @param ctx |
| * the <code>Context</code> |
| * @param node |
| * the parent <code>Node</code> |
| * @param pattern |
| * the pattern |
| * @return a <code>PropertyIterator</code> |
| * @throws RepositoryException |
| * if the underlying repository throws a |
| * <code>RepositoryException</code> |
| */ |
| public static PropertyIterator getProperties( |
| Context ctx, |
| Node node, |
| String pattern) throws RepositoryException { |
| if (pattern != null) { |
| return node.getProperties(pattern); |
| } else { |
| return node.getProperties(); |
| } |
| } |
| |
| /** |
| * @return the default <code>ResourceBundle</code> |
| */ |
| public static ResourceBundle getBundle() { |
| return bundle; |
| } |
| |
| /** |
| * Gets the <code>Item</code> s under the given <code>Node</code> that |
| * match the pattern |
| * @param ctx |
| * the <code>Context</code> |
| * @param node |
| * the parent <code>Node</code> |
| * @param pattern |
| * the pattern |
| * @return an <code>Iterator</code> with the <code>Item</code> s that |
| * match the given pattern. |
| * @throws RepositoryException |
| * if the underlying repository throws a |
| * <code>RepositoryException</code> |
| */ |
| public static Iterator getItems(Context ctx, Node node, String pattern) |
| throws RepositoryException { |
| return IteratorUtils.chainedIterator(getNodes(ctx, node, pattern), |
| getProperties(ctx, node, pattern)); |
| } |
| |
| } |