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-2006 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:
042: package org.netbeans.modules.web.struts;
043:
044: import java.io.IOException;
045: import java.util.ArrayList;
046: import java.util.Collections;
047: import java.util.List;
048: import java.util.StringTokenizer;
049: import java.util.logging.Level;
050: import java.util.logging.Logger;
051: import javax.lang.model.element.TypeElement;
052: import javax.lang.model.util.Elements;
053: import org.netbeans.api.java.source.ClasspathInfo;
054: import org.netbeans.api.java.source.CompilationController;
055: import org.netbeans.api.java.source.JavaSource;
056: import org.netbeans.api.java.source.Task;
057: import org.netbeans.api.project.FileOwnerQuery;
058: import org.netbeans.api.project.Project;
059: import org.netbeans.api.project.ProjectUtils;
060: import org.netbeans.api.project.SourceGroup;
061: import org.netbeans.api.project.Sources;
062: import org.netbeans.modules.j2ee.dd.api.common.InitParam;
063: import org.netbeans.modules.j2ee.dd.api.web.DDProvider;
064: import org.netbeans.modules.j2ee.dd.api.web.ServletMapping;
065: import org.netbeans.modules.j2ee.dd.api.web.WebApp;
066: import org.netbeans.modules.j2ee.dd.api.web.Servlet;
067: import org.netbeans.modules.web.api.webmodule.WebModule;
068: import org.netbeans.modules.web.api.webmodule.WebProjectConstants;
069: import org.netbeans.modules.web.struts.config.model.Action;
070: import org.netbeans.modules.web.struts.config.model.ActionMappings;
071: import org.netbeans.modules.web.struts.config.model.MessageResources;
072: import org.netbeans.modules.web.struts.config.model.StrutsConfig;
073: import org.netbeans.modules.web.struts.config.model.FormBeans;
074: import org.netbeans.modules.web.struts.config.model.FormBean;
075: import org.openide.filesystems.FileObject;
076: import org.openide.filesystems.FileUtil;
077: import org.openide.loaders.DataObject;
078: import org.openide.loaders.DataObjectNotFoundException;
079: import org.openide.util.Exceptions;
080:
081: /**
082: *
083: * @author petr
084: */
085: public class StrutsConfigUtilities {
086:
087: public static String DEFAULT_MODULE_NAME = "config"; //NOI18N
088: private static final int TYPE_ACTION = 0;
089: private static final int TYPE_FORM_BEAN = 1;
090: private static final int TYPE_MESSAGE_RESOURCES = 2;
091:
092: public static List getAllActionsInModule(StrutsConfigDataObject data) {
093: return createConfigElements(TYPE_ACTION, data);
094: }
095:
096: public static List getAllFormBeansInModule(
097: StrutsConfigDataObject data) {
098: return createConfigElements(TYPE_FORM_BEAN, data);
099: }
100:
101: public static List getAllMessageResourcesInModule(
102: StrutsConfigDataObject data) {
103: return createConfigElements(TYPE_MESSAGE_RESOURCES, data);
104: }
105:
106: private static List createConfigElements(int elementType,
107: StrutsConfigDataObject data) {
108: FileObject config = data.getPrimaryFile();
109: ArrayList list = new ArrayList();
110: WebModule wm = WebModule.getWebModule(config);
111: if (wm != null) {
112: FileObject ddFo = wm.getDeploymentDescriptor();
113: if (ddFo != null) {
114: String moduleName = getModuleName(config, ddFo);
115: if (moduleName == null) {
116: // the conf file is not in any module (is not declared in the web.xml)
117: try {
118: StrutsConfig sConfig = data
119: .getStrutsConfig(true);
120: switch (elementType) {
121: case TYPE_ACTION:
122: addActions(list, sConfig);
123: break;
124: case TYPE_FORM_BEAN:
125: addFormBeans(list, sConfig);
126: break;
127: case TYPE_MESSAGE_RESOURCES:
128: addMessageResource(list, sConfig);
129: break;
130: }
131: } catch (java.io.IOException e) {
132: // Do nothing
133: }
134: } else {
135: // the config file is in a Struts module, returns all actions from the
136: // conf files in the module
137: FileObject[] configs = getConfigFiles(moduleName,
138: ddFo);
139: DataObject dOb;
140: for (int i = 0; i < configs.length; i++) {
141: try {
142: dOb = DataObject.find(configs[i]);
143: } catch (DataObjectNotFoundException e) {
144: dOb = null;
145: }
146: if (dOb != null
147: && dOb instanceof StrutsConfigDataObject) {
148: StrutsConfigDataObject con = (StrutsConfigDataObject) dOb;
149: // the conf file is not in any module (is not declared in the web.xml)
150: try {
151: StrutsConfig sConfig = con
152: .getStrutsConfig(true);
153: switch (elementType) {
154: case TYPE_ACTION:
155: addActions(list, sConfig);
156: break;
157: case TYPE_FORM_BEAN:
158: addFormBeans(list, sConfig);
159: break;
160: case TYPE_MESSAGE_RESOURCES:
161: addMessageResource(list, sConfig);
162: break;
163: }
164: } catch (java.io.IOException e) {
165: // Do nothing
166: }
167: }
168: }
169: }
170: }
171: }
172: return list;
173: }
174:
175: private static void addActions(List list, StrutsConfig sConfig) {
176: ActionMappings mappings = sConfig.getActionMappings();
177: if (mappings == null)
178: return;
179: Action[] actions = mappings.getAction();
180: for (int j = 0; j < actions.length; j++)
181: list.add(actions[j]);
182: }
183:
184: private static void addFormBeans(List list, StrutsConfig sConfig) {
185: FormBeans formBeans = sConfig.getFormBeans();
186: if (formBeans == null)
187: return;
188: FormBean[] beans = formBeans.getFormBean();
189: for (int j = 0; j < beans.length; j++)
190: list.add(beans[j]);
191: }
192:
193: private static void addMessageResource(List list,
194: StrutsConfig sConfig) {
195: MessageResources[] rosources = sConfig.getMessageResources();
196: for (int j = 0; j < rosources.length; j++)
197: list.add(rosources[j]);
198: }
199:
200: /** Returns all configuration files for the module
201: **/
202: public static FileObject[] getConfigFiles(String module,
203: FileObject dd) {
204: FileObject docBase = WebModule.getWebModule(dd)
205: .getDocumentBase();
206: if (docBase == null)
207: return null;
208: Servlet servlet = getActionServlet(dd);
209: InitParam param = null;
210: if (module.equals(DEFAULT_MODULE_NAME))
211: param = (InitParam) servlet.findBeanByName("InitParam",
212: "ParamName", DEFAULT_MODULE_NAME);
213: else
214: param = (InitParam) servlet.findBeanByName("InitParam",
215: "ParamName", DEFAULT_MODULE_NAME + "/" + module);
216: FileObject[] configs = null;
217: if (param != null) {
218: StringTokenizer st = new StringTokenizer(param
219: .getParamValue(), ",");
220: configs = new FileObject[st.countTokens()];
221: int index = 0;
222: while (st.hasMoreTokens()) {
223: String name = st.nextToken().trim();
224: configs[index] = docBase.getFileObject(name);
225: index++;
226: }
227: }
228: return configs;
229: }
230:
231: /** Returns name of Struts module, which contains the configuration file.
232: */
233: public static String getModuleName(FileObject config, FileObject dd) {
234: String moduleName = null;
235: if (dd != null) {
236: Servlet servlet = getActionServlet(dd);
237: if (servlet != null) {
238: InitParam[] param = servlet.getInitParam();
239: StringTokenizer st = null;
240: int index = 0;
241:
242: while (moduleName == null && index < param.length) {
243: if (param[index].getParamName().trim().startsWith(
244: DEFAULT_MODULE_NAME)) {
245: String[] files = param[index].getParamValue()
246: .split(","); //NOI18N
247: for (int i = 0; i < files.length; i++) {
248: String file = files[i];
249: if (config.getPath().endsWith(file)) {
250: if (!param[index].getParamName().trim()
251: .equals(DEFAULT_MODULE_NAME)) {
252: moduleName = param[index]
253: .getParamName()
254: .trim()
255: .substring(
256: DEFAULT_MODULE_NAME
257: .length() + 1);
258: } else {
259: moduleName = DEFAULT_MODULE_NAME;
260: }
261: break;
262: }
263: }
264:
265: }
266: index++;
267: }
268: }
269: }
270: return moduleName;
271: }
272:
273: public static Servlet getActionServlet(FileObject dd) {
274: if (dd == null) {
275: return null;
276: }
277: try {
278: WebApp webApp = DDProvider.getDefault().getDDRoot(dd);
279: Servlet servlet = (Servlet) webApp.findBeanByName(
280: "Servlet", "ServletClass",
281: "org.apache.struts.action.ActionServlet"); //NOI18N;
282: if (servlet == null) {
283: // check whether a servler class doesn't extend org.apache.struts.action.ActionServlet
284: final Servlet[] servlets = webApp.getServlet();
285:
286: ClasspathInfo cpi = ClasspathInfo.create(dd);
287: JavaSource js = JavaSource.create(cpi,
288: Collections.EMPTY_LIST);
289: final int[] index = new int[] { -1 };
290: js.runUserActionTask(new Task<CompilationController>() {
291: public void run(CompilationController cc)
292: throws Exception {
293: Elements elements = cc.getElements();
294: TypeElement strutsServletElement = elements
295: .getTypeElement("org.apache.struts.action.ActionServlet"); //NOI18N
296: TypeElement servletElement;
297: if (strutsServletElement != null) {
298: for (int i = 0; i < servlets.length; i++) {
299: servletElement = elements
300: .getTypeElement(servlets[i]
301: .getServletClass());
302: if (servletElement != null
303: && cc
304: .getTypes()
305: .isSubtype(
306: servletElement
307: .asType(),
308: strutsServletElement
309: .asType())) {
310: index[0] = i;
311: continue;
312: }
313: }
314: }
315: }
316:
317: }, false);
318:
319: if (index[0] > -1)
320: servlet = servlets[index[0]];
321: }
322: return servlet;
323: } catch (java.io.IOException e) {
324: Exceptions.printStackTrace(e);
325: return null;
326: }
327: }
328:
329: /** Returns the mapping for the Struts Action Servlet.
330: */
331: public static String getActionServletMapping(FileObject dd) {
332: Servlet servlet = getActionServlet(dd);
333: if (servlet != null) {
334: try {
335: WebApp webApp = DDProvider.getDefault().getDDRoot(dd);
336: ServletMapping[] mappings = webApp.getServletMapping();
337: for (int i = 0; i < mappings.length; i++) {
338: if (mappings[i].getServletName().equals(
339: servlet.getServletName()))
340: return mappings[i].getUrlPattern();
341: }
342: } catch (java.io.IOException e) {
343:
344: }
345: }
346: return null;
347: }
348:
349: /** Returns relative path for all struts configuration files in the web module
350: */
351: public static String[] getConfigFiles(FileObject dd) {
352: if (dd != null) {
353: Servlet servlet = getActionServlet(dd);
354: if (servlet != null) {
355: InitParam[] params = servlet.getInitParam();
356: List list = new ArrayList();
357: for (int i = 0; i < params.length; i++) {
358: String paramName = params[i].getParamName();
359: if (paramName != null) {
360: if (paramName.startsWith(DEFAULT_MODULE_NAME)) {
361: String[] files = params[i].getParamValue()
362: .split(","); //NOI18N
363: for (int j = 0; j < files.length; j++)
364: list.add(files[j]);
365: }
366: }
367: }
368: String[] result = new String[list.size()];
369: list.toArray(result);
370: return result;
371: }
372: }
373: return new String[] {};
374: }
375:
376: /** Returns all configuration files in the web module
377: */
378: public static FileObject[] getConfigFilesFO(FileObject dd) {
379: if (dd != null) {
380: FileObject docBase = WebModule.getWebModule(dd)
381: .getDocumentBase();
382: if (docBase == null)
383: return null;
384: Servlet servlet = getActionServlet(dd);
385: if (servlet != null) {
386: InitParam[] params = servlet.getInitParam();
387: List list = new ArrayList();
388: FileObject file;
389: for (int i = 0; i < params.length; i++) {
390: String paramName = params[i].getParamName();
391: if (paramName != null) {
392: if (paramName.startsWith(DEFAULT_MODULE_NAME)) { //NOI18N
393: String[] files = params[i].getParamValue()
394: .split(","); //NOI18N
395: for (int j = 0; j < files.length; j++) {
396: file = docBase.getFileObject(files[j]);
397: if (file != null)
398: list.add(file);
399: }
400: }
401: }
402: }
403: FileObject[] result = new FileObject[list.size()];
404: list.toArray(result);
405: return result;
406: }
407: }
408: return new FileObject[] {};
409: }
410:
411: /** Returns WebPages for the project, where the fo is located.
412: */
413: public static SourceGroup[] getDocBaseGroups(FileObject fo)
414: throws java.io.IOException {
415: Project proj = FileOwnerQuery.getOwner(fo);
416: if (proj == null)
417: return new SourceGroup[] {};
418: Sources sources = ProjectUtils.getSources(proj);
419: return sources
420: .getSourceGroups(WebProjectConstants.TYPE_DOC_ROOT);
421: }
422:
423: public static String getResourcePath(SourceGroup[] groups,
424: FileObject fo, char separator, boolean withExt) {
425: for (int i = 0; i < groups.length; i++) {
426: FileObject root = groups[i].getRootFolder();
427: if (FileUtil.isParentOf(root, fo)) {
428: String relativePath = FileUtil
429: .getRelativePath(root, fo);
430: if (relativePath != null) {
431: if (separator != '/')
432: relativePath = relativePath.replace('/',
433: separator);
434: if (!withExt) {
435: int index = relativePath.lastIndexOf((int) '.');
436: if (index > 0)
437: relativePath = relativePath.substring(0,
438: index);
439: }
440: return relativePath;
441: } else {
442: return "";
443: }
444: }
445: }
446: return "";
447: }
448:
449: /**
450: * Get the welcome file based on the URL Pattern and the Page Name.
451: * @param URLPattern the URL Pattern
452: * @param pageName the Page Name
453: * @return If successful, returns the welcome file, "do/" + pageName if unsuccessful.
454: */
455: public static String getWelcomeFile(String URLPattern,
456: String pageName) {
457: int indWild = URLPattern.indexOf("*"); // NOI18N
458: if (indWild >= 0) {
459: String pPrefix = URLPattern.substring(0, indWild);
460: String pSuffix = URLPattern.substring(indWild + 1);
461:
462: if (pPrefix.length() > 0) {
463: while (pPrefix.startsWith("/")) { // NOI18N
464: pPrefix = pPrefix.substring(1);
465: }
466: }
467:
468: return pPrefix + pageName + pSuffix;
469: }
470:
471: return "do/" + pageName;
472: }
473:
474: public static String getActionAsResource(WebModule wm, String action) {
475: String resource = "";
476: String mapping = StrutsConfigUtilities
477: .getActionServletMapping(wm.getDeploymentDescriptor());
478: if (mapping != null && mapping.length() > 0) {
479: if (mapping.startsWith("*."))
480: resource = action + mapping.substring(1);
481: else if (mapping.endsWith("/*"))
482: resource = mapping.substring(0, mapping.length() - 2)
483: + action;
484: }
485: return resource;
486: }
487:
488: public static String getActionAsResource(String mapping,
489: String action) {
490: String resource = "";
491: if (mapping != null && mapping.length() > 0) {
492: if (mapping.startsWith("*."))
493: resource = action + mapping.substring(1);
494: else if (mapping.endsWith("/*"))
495: resource = mapping.substring(0, mapping.length() - 2)
496: + action;
497: }
498: return resource;
499: }
500:
501: public static MessageResources getDefatulMessageResource(
502: FileObject dd) {
503: FileObject[] files = getConfigFilesFO(dd);
504: MessageResources resource = null;
505: int index = 0;
506: DataObject configDO;
507: try {
508: while (resource == null && index < files.length) {
509: configDO = DataObject.find(files[index]);
510: if (configDO != null
511: && configDO instanceof StrutsConfigDataObject) {
512: StrutsConfig strutsConfig = ((StrutsConfigDataObject) configDO)
513: .getStrutsConfig();
514: // we need to chech, whether the config is parseable
515: if (strutsConfig != null) {
516: MessageResources[] resources = strutsConfig
517: .getMessageResources();
518: for (int i = 0; i < resources.length; i++) {
519: if (resources[i].getAttributeValue("key") == null) { //NOI18N
520: resource = resources[i];
521: break;
522: }
523: }
524: }
525: }
526: index++;
527: }
528: } catch (DataObjectNotFoundException ex) {
529: Logger.getLogger("global").log(Level.WARNING, null, ex);
530: } catch (IOException ex) {
531: Logger.getLogger("global").log(Level.WARNING, null, ex);
532: }
533: return resource;
534: }
535: }
|