001/*
002 * (C) Copyright 2006-2008 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     bstefanescu
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.webengine.model.impl;
023
024import java.io.File;
025import java.util.ArrayList;
026import java.util.HashSet;
027import java.util.List;
028import java.util.Set;
029
030import org.nuxeo.common.xmap.annotation.XNode;
031import org.nuxeo.common.xmap.annotation.XNodeList;
032import org.nuxeo.common.xmap.annotation.XObject;
033import org.nuxeo.ecm.webengine.ResourceBinding;
034import org.nuxeo.ecm.webengine.WebEngine;
035import org.nuxeo.ecm.webengine.app.WebEngineModule;
036import org.nuxeo.ecm.webengine.model.LinkDescriptor;
037import org.nuxeo.ecm.webengine.model.Module;
038import org.nuxeo.ecm.webengine.model.WebContext;
039import org.nuxeo.ecm.webengine.model.exceptions.WebResourceNotFoundException;
040
041/**
042 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
043 */
044@XObject("module")
045public class ModuleConfiguration implements Cloneable {
046
047    /**
048     * A web module may have multiple roots
049     *
050     * @deprecated you should use new module definition - through {@link WebEngineModule}
051     */
052    @Deprecated
053    @XNode("@path")
054    public String path;
055
056    /**
057     * @deprecated you should use new module definition - through {@link WebEngineModule}
058     */
059    @Deprecated
060    @XNode("@root-type")
061    public String rootType;
062
063    /**
064     * Paths of root resources in the module. This is replacing the deprecated root-type.
065     */
066    public Class<?>[] roots;
067
068    @XNode("@extends")
069    public String base;
070
071    @XNode("@name")
072    public String name;
073
074    /**
075     * Use module links instead. If a module doesn't declare a module item it will be headless by default. Still used
076     * for compatibility mode - for those modules not yet using moduleItems.
077     */
078    @Deprecated
079    @XNode("@headless")
080    public boolean isHeadless;
081
082    /**
083     * A list of entry points into the module - to be shown in the main webengine page. This is optional and may be
084     * ignored if your don't want to provide shortcuts to your module entry points.
085     */
086    @XNodeList(value = "shortcuts/shortcut", type = ArrayList.class, componentType = ModuleShortcut.class, nullByDefault = true)
087    public List<ModuleShortcut> moduleShortcuts;
088
089    /**
090     * Web Types explicitly declared. If null no web types were explicitly declared and old type loading method from the
091     * generated web-types file should be used.
092     */
093    public Class<?>[] types;
094
095    /**
096     * The module directory. Must be set by the client before registering the descriptor.
097     */
098    @XNode("home")
099    public File directory;
100
101    @XNodeList(value = "fragments/directory", type = ArrayList.class, componentType = File.class, nullByDefault = false)
102    public List<File> fragmentDirectories = new ArrayList<File>();
103
104    /**
105     * The module configuration file (this will be set by the module config parser)
106     */
107    public File file;
108
109    @XNodeList(value = "nature", type = HashSet.class, componentType = String.class, nullByDefault = true)
110    public Set<String> natures;
111
112    @XNodeList(value = "links/link", type = ArrayList.class, componentType = LinkDescriptor.class, nullByDefault = true)
113    public List<LinkDescriptor> links;
114
115    /**
116     * @deprecated resources are deprecated - you should use a jax-rs application to declare more resources.
117     */
118    @Deprecated
119    @XNodeList(value = "resources/resource", type = ArrayList.class, componentType = ResourceBinding.class, nullByDefault = true)
120    public List<ResourceBinding> resources;
121
122    @XNode("templateFileExt")
123    public String templateFileExt = "ftl";
124
125    @XNodeList(value = "media-types/media-type", type = MediaTypeRef[].class, componentType = MediaTypeRef.class, nullByDefault = true)
126    public MediaTypeRef[] mediatTypeRefs;
127
128    public WebEngine engine;
129
130    private ModuleImpl module;
131
132    public boolean allowHostOverride;
133
134    public ModuleConfiguration() {
135    }
136
137    public ModuleConfiguration(WebEngine engine) {
138        this.engine = engine;
139    }
140
141    public WebEngine getEngine() {
142        return engine;
143    }
144
145    public void setEngine(WebEngine engine) {
146        this.engine = engine;
147    }
148
149    public String getName() {
150        return name;
151    }
152
153    public List<ModuleShortcut> getShortcuts() {
154        return moduleShortcuts;
155    }
156
157    public List<LinkDescriptor> getLinks() {
158        return links;
159    }
160
161    public File getDirectory() {
162        return directory;
163    }
164
165    public String getBase() {
166        return base;
167    }
168
169    public Module get(WebContext context) {
170        if (module == null) {
171            Module superModule = null;
172            if (base != null) { // make sure super modules are resolved
173                ModuleConfiguration superM = engine.getModuleManager().getModule(base);
174                if (superM == null) {
175                    throw new WebResourceNotFoundException("The module '" + name
176                            + "' cannot be loaded since it's super module '" + base + "' cannot be found");
177                }
178                // force super module loading
179                superModule = superM.get(context);
180            }
181            module = new ModuleImpl(engine, (ModuleImpl) superModule, this, context.getServerInjectableProviderContext());
182        }
183        return module;
184    }
185
186    public void flushCache() {
187        if (module == null) {
188            return;
189        }
190        module.flushCache();
191        module = null;
192    }
193
194    public boolean isLoaded() {
195        return module != null;
196    }
197
198    public boolean isHeadless() {
199        return isHeadless;
200    }
201
202}