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 041import com.sun.jersey.server.impl.inject.ServerInjectableProviderContext; 042 043/** 044 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 045 */ 046@XObject("module") 047public class ModuleConfiguration { 048 049 /** 050 * A web module may have multiple roots 051 * 052 * @deprecated you should use new module definition - through {@link WebEngineModule} 053 */ 054 @Deprecated 055 @XNode("@path") 056 public String path; 057 058 /** 059 * @deprecated you should use new module definition - through {@link WebEngineModule} 060 */ 061 @Deprecated 062 @XNode("@root-type") 063 public String rootType; 064 065 /** 066 * Paths of root resources in the module. This is replacing the deprecated root-type. 067 */ 068 public Class<?>[] roots; 069 070 @XNode("@extends") 071 public String base; 072 073 @XNode("@name") 074 public String name; 075 076 /** 077 * Use module links instead. If a module doesn't declare a module item it will be headless by default. Still used 078 * for compatibility mode - for those modules not yet using moduleItems. 079 */ 080 @Deprecated 081 @XNode("@headless") 082 public boolean isHeadless; 083 084 /** 085 * A list of entry points into the module - to be shown in the main webengine page. This is optional and may be 086 * ignored if your don't want to provide shortcuts to your module entry points. 087 */ 088 @XNodeList(value = "shortcuts/shortcut", type = ArrayList.class, componentType = ModuleShortcut.class, nullByDefault = true) 089 public List<ModuleShortcut> moduleShortcuts; 090 091 /** 092 * Web Types explicitly declared. If null no web types were explicitly declared and old type loading method from the 093 * generated web-types file should be used. 094 */ 095 public Class<?>[] types; 096 097 /** 098 * The module directory. Must be set by the client before registering the descriptor. 099 */ 100 @XNode("home") 101 public File directory; 102 103 @XNodeList(value = "fragments/directory", type = ArrayList.class, componentType = File.class, nullByDefault = false) 104 public List<File> fragmentDirectories = new ArrayList<File>(); 105 106 /** 107 * The module configuration file (this will be set by the module config parser) 108 */ 109 public File file; 110 111 @XNodeList(value = "nature", type = HashSet.class, componentType = String.class, nullByDefault = true) 112 public Set<String> natures; 113 114 @XNodeList(value = "links/link", type = ArrayList.class, componentType = LinkDescriptor.class, nullByDefault = true) 115 public List<LinkDescriptor> links; 116 117 /** 118 * @deprecated resources are deprecated - you should use a jax-rs application to declare more resources. 119 */ 120 @Deprecated 121 @XNodeList(value = "resources/resource", type = ArrayList.class, componentType = ResourceBinding.class, nullByDefault = true) 122 public List<ResourceBinding> resources; 123 124 @XNode("templateFileExt") 125 public String templateFileExt = "ftl"; 126 127 @XNodeList(value = "media-types/media-type", type = MediaTypeRef[].class, componentType = MediaTypeRef.class, nullByDefault = true) 128 public MediaTypeRef[] mediatTypeRefs; 129 130 public WebEngine engine; 131 132 // volatile for double-checked locking 133 private volatile ModuleImpl module; 134 135 public boolean allowHostOverride; 136 137 public ModuleConfiguration() { 138 } 139 140 public ModuleConfiguration(WebEngine engine) { 141 this.engine = engine; 142 } 143 144 public WebEngine getEngine() { 145 return engine; 146 } 147 148 public void setEngine(WebEngine engine) { 149 this.engine = engine; 150 } 151 152 public String getName() { 153 return name; 154 } 155 156 public List<ModuleShortcut> getShortcuts() { 157 return moduleShortcuts; 158 } 159 160 public List<LinkDescriptor> getLinks() { 161 return links; 162 } 163 164 public File getDirectory() { 165 return directory; 166 } 167 168 public String getBase() { 169 return base; 170 } 171 172 public Module get(WebContext context) { 173 ModuleImpl mod = module; 174 if (mod == null) { 175 synchronized (this) { 176 mod = module; 177 if (mod == null) { 178 Module superModule = null; 179 if (base != null) { // make sure super modules are resolved 180 ModuleConfiguration superM = engine.getModuleManager().getModule(base); 181 if (superM == null) { 182 throw new WebResourceNotFoundException("The module '" + name 183 + "' cannot be loaded since its super module '" + base + "' cannot be found"); 184 } 185 // force super module loading 186 superModule = superM.get(context); 187 } 188 ServerInjectableProviderContext sic = context.getServerInjectableProviderContext(); 189 mod = new ModuleImpl(engine, (ModuleImpl) superModule, this, sic); 190 if (sic != null) { 191 // cache the module only if it has a ServerInjectableProviderContext 192 module = mod; 193 } 194 } 195 } 196 } 197 return mod; 198 } 199 200 public void flushCache() { 201 synchronized (this) { 202 if (module == null) { 203 return; 204 } 205 module.flushCache(); 206 module = null; 207 } 208 } 209 210 public boolean isLoaded() { 211 return module != null; 212 } 213 214 public boolean isHeadless() { 215 return isHeadless; 216 } 217 218}