001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.web.jsf.api;
042:
043: import java.util.ArrayList;
044: import java.util.Collection;
045: import java.util.Iterator;
046: import java.util.WeakHashMap;
047: import java.util.Map;
048: import java.lang.ref.WeakReference;
049: import org.netbeans.modules.j2ee.dd.api.web.DDProvider;
050: import org.netbeans.modules.j2ee.dd.api.web.Servlet;
051: import org.netbeans.modules.j2ee.dd.api.web.ServletMapping;
052: import org.netbeans.modules.j2ee.dd.api.web.WebApp;
053: import org.netbeans.modules.web.api.webmodule.WebModule;
054: import org.netbeans.modules.web.jsf.JSFConfigUtilities;
055: import org.netbeans.modules.web.jsf.api.facesmodel.FacesConfig;
056: import org.netbeans.modules.web.jsf.api.facesmodel.JSFConfigModel;
057: import org.netbeans.modules.web.jsf.api.facesmodel.JSFConfigModelFactory;
058: import org.netbeans.modules.web.jsf.api.facesmodel.ManagedBean;
059: import org.netbeans.modules.xml.retriever.catalog.Utilities;
060: import org.netbeans.modules.xml.xam.ModelSource;
061: import org.netbeans.modules.xml.xam.locator.CatalogModelException;
062: import org.openide.filesystems.FileObject;
063: import org.openide.util.Exceptions;
064:
065: /**
066: *
067: * @author Petr Pisl
068: * @author Po-Ting Wu
069: */
070: public class ConfigurationUtils {
071:
072: // We can override equals() and hashcode() methods here for accepting 2 keys in HashMap
073: // However due to the performance issue and clear codes, use 2 HashMap here will be better
074: private static WeakHashMap<FileObject, WeakReference<JSFConfigModel>> configModelsEditable = new WeakHashMap();
075: private static WeakHashMap<FileObject, WeakReference<JSFConfigModel>> configModelsNonEditable = new WeakHashMap();
076:
077: /**
078: * This methods returns the model source for the faces config file.
079: * @param confFile - the faces config file
080: * @param editable - if the source will be editable. Clients should use true.
081: * @return The ModelSource for the configuration file. If the file is not faces config file
082: * or a version which is not handled, then returns null.
083: */
084: public static synchronized JSFConfigModel getConfigModel(
085: FileObject confFile, boolean editable) {
086: JSFConfigModel configModel = null;
087: if (confFile != null && confFile.isValid()) {
088: Map<FileObject, WeakReference<JSFConfigModel>> configModelsRef = editable ? configModelsEditable
089: : configModelsNonEditable;
090: WeakReference<JSFConfigModel> configModelRef = configModelsRef
091: .get(confFile);
092: if (configModelRef != null) {
093: configModel = configModelRef.get();
094: if (configModel != null) {
095: return configModel;
096: }
097:
098: configModelsRef.remove(confFile);
099: }
100:
101: try {
102: ModelSource modelSource = Utilities.createModelSource(
103: confFile, editable);
104: configModel = JSFConfigModelFactory.getInstance()
105: .getModel(modelSource);
106: configModelsRef.put(confFile,
107: new WeakReference<JSFConfigModel>(configModel));
108: } catch (CatalogModelException ex) {
109: java.util.logging.Logger.getLogger("global").log(
110: java.util.logging.Level.SEVERE,
111: ex.getMessage(), ex);
112: }
113: }
114: return configModel;
115: }
116:
117: /**
118: * The methods finds the definition of the Faces Servlet in the deployment descriptor
119: * of the given web module.
120: * @param webModule the given web module, where the Faces Servlet is.
121: * @return Faces Servlet definition or null if the Faces Servlet definition is not
122: * found in the given web module.
123: */
124: public static Servlet getFacesServlet(WebModule webModule) {
125: FileObject deploymentDescriptor = webModule
126: .getDeploymentDescriptor();
127: if (deploymentDescriptor == null) {
128: return null;
129: }
130: try {
131: WebApp webApp = DDProvider.getDefault().getDDRoot(
132: deploymentDescriptor);
133:
134: // Try to find according the servlet class name. The javax.faces.webapp.FacesServlet is final, so
135: // it can not be extended.
136: return (Servlet) webApp.findBeanByName("Servlet",
137: "ServletClass", "javax.faces.webapp.FacesServlet"); //NOI18N;
138: } catch (java.io.IOException e) {
139: return null;
140: }
141: }
142:
143: /** Returns the mapping for the Faces Servlet.
144: * @param webModule web module, where the JSF framework should be defined
145: * @return The maping for the faces servlet. Null if the web module doesn't
146: * contains definition of faces servlet.
147: */
148: public static String getFacesServletMapping(WebModule webModule) {
149: FileObject deploymentDescriptor = webModule
150: .getDeploymentDescriptor();
151: Servlet servlet = getFacesServlet(webModule);
152: if (servlet != null) {
153: try {
154: WebApp webApp = DDProvider.getDefault().getDDRoot(
155: deploymentDescriptor);
156: ServletMapping[] mappings = webApp.getServletMapping();
157: for (int i = 0; i < mappings.length; i++) {
158: if (mappings[i].getServletName().equals(
159: servlet.getServletName()))
160: return mappings[i].getUrlPattern();
161: }
162: } catch (java.io.IOException e) {
163: Exceptions.printStackTrace(e);
164: }
165: }
166: return null;
167: }
168:
169: /**
170: * The method returns all faces configuration files in the web module.
171: * If there is faces-config.xml file in the web project, then it's returned
172: * as the first one. Other configuration files are in the same order as are
173: * listed in the javax.faces.CONFIG_FILES attribute in the web.xml file.
174: * @param webModule - the web module, where you want to find the faces
175: * configuration files
176: * @return array of all faces configuration files. If there are not any
177: * configuration file, then empty array is returned.
178: **/
179:
180: public static FileObject[] getFacesConfigFiles(WebModule webModule) {
181: String[] sFiles = JSFConfigUtilities.getConfigFiles(webModule);
182: if (sFiles.length > 0) {
183: FileObject documentBase = webModule.getDocumentBase();
184: ArrayList files = new ArrayList();
185: FileObject file;
186: for (int i = 0; i < sFiles.length; i++) {
187: file = documentBase.getFileObject(sFiles[i]);
188: if (file != null)
189: files.add(file);
190: }
191: return (FileObject[]) files.toArray(new FileObject[files
192: .size()]);
193: }
194: return new FileObject[0];
195: }
196:
197: /**
198: * Translates an URI to be executed with faces serlvet with the given mapping.
199: * For example, the servlet has mapping <i>*.jsf</i> then uri <i>hello.jsp</i> will be
200: * translated to <i>hello.jsf</i>. In the case where the mapping is <i>/faces/*</i>
201: * will be translated to <i>faces/hello.jsp<i>.
202: *
203: * @param mapping The servlet mapping
204: * @param uri The original URI
205: * @return The translated URI
206: */
207: public static String translateURI(String mapping, String uri) {
208: String resource = "";
209: if (mapping != null && mapping.length() > 0) {
210: if (mapping.startsWith("*.")) {
211: if (uri.indexOf('.') > 0)
212: resource = uri.substring(0, uri.lastIndexOf('.'))
213: + mapping.substring(1);
214: else
215: resource = uri + mapping.substring(1);
216: } else if (mapping.endsWith("/*"))
217: resource = mapping.substring(1, mapping.length() - 1)
218: + uri;
219: }
220: return resource;
221: }
222:
223: /**
224: * Helper method which finds the faces configuration file, where is the managed bean
225: * defined.
226: * @param webModule the web module, wher the managed bean is defined.
227: * @param name Name of the managed bean.
228: * @return faces configuration file, where the managed bean is defined. Null, if a bean
229: * with the given name is not defined in the web module.
230: */
231: public static FileObject findFacesConfigForManagedBean(
232: WebModule webModule, String name) {
233: FileObject[] configs = ConfigurationUtils
234: .getFacesConfigFiles(webModule);
235:
236: for (int i = 0; i < configs.length; i++) {
237: //DataObject dObject = DataObject.find(configs[i]);
238: FacesConfig facesConfig = getConfigModel(configs[i], true)
239: .getRootComponent();
240: Collection<ManagedBean> beans = facesConfig
241: .getManagedBeans();
242: for (Iterator<ManagedBean> it = beans.iterator(); it
243: .hasNext();) {
244: ManagedBean managedBean = it.next();
245: if (name.equals(managedBean.getManagedBeanName()))
246: return configs[i];
247: }
248:
249: }
250: return null;
251: }
252:
253: }
|