001/*
002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.webengine;
021
022import javax.ws.rs.Path;
023
024import org.nuxeo.common.xmap.annotation.XNode;
025import org.nuxeo.common.xmap.annotation.XObject;
026
027/**
028 * Defines a JAX-RS root resource binding. This is an extension to JAX-RS to be able to declare root resource binding
029 * dynamically without using {@link Path} annotations on classes.
030 *
031 * @deprecated resources are deprecated - you should use a jax-rs application to declare more resources.
032 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
033 * @see Path
034 */
035@XObject(value = "resource", order = { "@path", "@class" })
036public class ResourceBinding {
037
038    @XNode("@path")
039    public String path;
040
041    @XNode("@singleton")
042    public boolean singleton = false;
043
044    private boolean hasUserPath = false;
045
046    /**
047     * Use this to specify the resource class.
048     */
049    @XNode("@class")
050    public String className;
051
052    public Class<?> clazz;
053
054    public ResourceBinding() {
055    }
056
057    public ResourceBinding(String path, Class<?> clazz, boolean singleton) {
058        this.path = path;
059        this.clazz = clazz;
060        this.singleton = singleton;
061    }
062
063    /**
064     * Must be called before using this binding.
065     */
066    public void resolve(WebEngine engine) throws ClassNotFoundException {
067        if (clazz == null) {
068            clazz = engine.loadClass(className);
069            if (path == null) {
070                hasUserPath = false;
071                Path p = clazz.getAnnotation(Path.class);
072                if (p == null) {
073                    throw new WebException("Invalid resource binding. Path not defined");
074                }
075                path = p.value();
076            } else {
077                hasUserPath = true;
078            }
079        }
080    }
081
082    public void reload(WebEngine engine) throws ClassNotFoundException {
083        clazz = null;
084        resolve(engine);
085    }
086
087    @Override
088    public int hashCode() {
089        return path.hashCode();
090    }
091
092    @Override
093    public boolean equals(Object obj) {
094        if (obj == this) {
095            return true;
096        }
097        if (obj instanceof ResourceBinding) {
098            ResourceBinding binding = (ResourceBinding) obj;
099            return binding.path.equals(path) && binding.clazz == clazz;
100        }
101        return false;
102    }
103
104    public static ResourceBinding fromAnnotation(Class<?> clazz) {
105        Path path = clazz.getAnnotation(Path.class);
106        ResourceBinding binding = null;
107        if (path != null) {
108            binding = new ResourceBinding();
109            binding.path = path.value();
110            binding.clazz = clazz;
111        }
112        return binding;
113    }
114
115    public String getPath() {
116        return path;
117    }
118
119    public Class<?> getClazz() {
120        return clazz;
121    }
122
123    public boolean isSingleton() {
124        return singleton;
125    }
126
127    @Override
128    public String toString() {
129        return path + " -> " + clazz;
130    }
131
132}