001: /**
002: * JOnAS : Java(TM) OpenSource Application Server
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or any later version.
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: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
017: * USA
018: *
019: * Initial Developer : Guillaume Sauthier
020: * --------------------------------------------------------------------------
021: * $Id: WsEndpointDDModifier.java 9457 2006-08-24 12:58:41Z sauthieg $
022: * --------------------------------------------------------------------------
023: */package org.objectweb.jonas_ws.wsgen.ddmodifier;
024:
025: import org.objectweb.util.monolog.api.BasicLevel;
026: import org.w3c.dom.Document;
027: import org.w3c.dom.Element;
028: import org.w3c.dom.Node;
029: import org.w3c.dom.NodeList;
030: import org.w3c.dom.Text;
031:
032: /**
033: * Modify a Deployment Desc for Endpoint. Wrapper around a web.xml DOM.
034: *
035: * @author Guillaume Sauthier
036: */
037: public class WsEndpointDDModifier extends DeploymentDescModifier {
038:
039: /**
040: * servlet Element name
041: */
042: private static final String SERVLET = "servlet";
043:
044: /**
045: * servlet-name Element name
046: */
047: private static final String SERVLET_NAME = "servlet-name";
048:
049: /**
050: * servlet-class Element name
051: */
052: private static final String SERVLET_CLASS = "servlet-class";
053:
054: /**
055: * servlet-mapping Element name
056: */
057: private static final String SERVLET_MAPPING = "servlet-mapping";
058:
059: /**
060: * url-pattern Element name
061: */
062: private static final String URL_MAPPING = "url-pattern";
063:
064: /**
065: * init-param Element name
066: */
067: private static final String INIT_PARAM = "init-param";
068:
069: /**
070: * param-name Element name
071: */
072: private static final String PARAM_NAME = "param-name";
073:
074: /**
075: * param-value Element name
076: */
077: private static final String PARAM_VALUE = "param-value";
078:
079: /**
080: * security-role-ref Element name
081: */
082: private static final String SECURITY_ROLE_REF = "security-role-ref";
083:
084: /**
085: * url-pattern Element name
086: */
087: private static final String URL_PATTERN = "url-pattern";
088:
089: /**
090: * security-constraint Element name
091: */
092: private static final String SECURITY_CONSTRAINT = "security-constraint";
093:
094: /**
095: * login-config Element name
096: */
097: private static final String LOGIN_CONFIG = "login-config";
098:
099: /**
100: * security-role Element name
101: */
102: private static final String SECURITY_ROLE = "security-role";
103:
104: /**
105: * role-name Element name.
106: */
107: private static final String ROLE_NAME = "role-name";
108:
109: /**
110: * Used to retrieve any Element childrens.
111: */
112: private static final String ANY_TAG_NAME = "*";
113:
114: /**
115: * Creates a new WsEndpointDDModifier object.
116: * @param web web.xml document
117: */
118: public WsEndpointDDModifier(Document web) {
119: super (web.getDocumentElement(), web);
120: }
121:
122: /**
123: * Add a new <code>servlet</code> element in the web.xml.
124: * @param name servlet name.
125: * @param classname servlet fully qualified classname.
126: */
127: public void addServlet(String name, String classname) {
128: Element servlet = newJ2EEElement(SERVLET);
129: Element servletName = newJ2EEElement(SERVLET_NAME, name);
130: Element servletClass = newJ2EEElement(SERVLET_CLASS, classname);
131:
132: servlet.appendChild(servletName);
133: servlet.appendChild(servletClass);
134:
135: // add servlet in the webapp Element
136: getElement().appendChild(servlet);
137:
138: }
139:
140: /**
141: * Add a new security-constraint element into the web.xml
142: *
143: * @param securityConstraint A node containing the security-constraint setting
144: */
145: public void addEndpointSecurityConstraint(Node securityConstraint) {
146: Element sConstraintElement = newJ2EEElement(SECURITY_CONSTRAINT);
147:
148: // securityConstraint comes from another document, therefore have to
149: // import first
150: Node newSecurityConstraint = getDocument().importNode(
151: securityConstraint, true);
152:
153: while (newSecurityConstraint.hasChildNodes()) {
154: sConstraintElement.appendChild(newSecurityConstraint
155: .getFirstChild());
156: }
157:
158: // add security-constraint to webapp
159: getElement().appendChild(sConstraintElement);
160: }
161:
162: /**
163: * Add a new login-config element into the web.xml
164: *
165: * @param loginConfig An element constaining the login-config setting
166: */
167: public void addEndpointLoginConfig(Element loginConfig) {
168:
169: // A <web-app> MUST only have 1 <login-config> element
170: // If the same login-config is already there, that's fine.
171: // But if there is *another* login-config, we must throw an Exception
172:
173: // Try to get a reference on a login-config element
174: NodeList configs = getElement().getElementsByTagNameNS(J2EE_NS,
175: LOGIN_CONFIG);
176: if (configs.getLength() == 0) {
177: // no login-config, we can insert our own ...
178: Element myLoginConfig = newJ2EEElement(LOGIN_CONFIG);
179:
180: // loginConfig comes from another document, therefore have to import
181: // first
182: Node importedLoginConfig = getDocument().importNode(
183: loginConfig, true);
184:
185: while (importedLoginConfig.hasChildNodes()) {
186: myLoginConfig.appendChild(importedLoginConfig
187: .getFirstChild());
188: }
189:
190: // add login-config to webapp
191: getElement().appendChild(myLoginConfig);
192: } else {
193: // Ooops, found another login-config
194: // Check if the login-config is the same than our own...
195:
196: // There can be only 1 login-config per web-app
197: Element config = (Element) configs.item(0);
198:
199: // If nodes are not the same
200: if (!areChildNodesIdentical(config, loginConfig)) {
201: String msg = "Cannot insert the new login-config element (login-config cannot "
202: + "be defined twice, even with different values !) : "
203: + loginConfig;
204: throw new IllegalStateException(msg);
205: }
206: // OK, That's fine, we can let it 'as is'
207:
208: }
209: }
210:
211: /**
212: * @param first first Node to compare childs.
213: * @param second second nodes to compare childs.
214: * @return Returns <code>true</code> if nodes childs are identical.
215: */
216: private static boolean areChildNodesIdentical(final Element first,
217: final Element second) {
218:
219: // Check childrens
220: boolean identical = true;
221: // by using getElementsByTagName, we avoid to check meaningless Text nodes
222: NodeList firstChilds = first.getElementsByTagName(ANY_TAG_NAME);
223: NodeList secondChilds = second
224: .getElementsByTagName(ANY_TAG_NAME);
225:
226: if (firstChilds.getLength() != secondChilds.getLength()) {
227: // one of the 2 nodes have more childrens, so they are not
228: // identical.
229:
230: return false;
231: } else if (firstChilds.getLength() == 0) {
232: // no child *Element*
233: // get the elements inner value
234: String one = first.getFirstChild().getNodeValue();
235: String two = second.getFirstChild().getNodeValue();
236:
237: // End recursion
238: return one.equals(two);
239:
240: } else {
241: // There is some children Elements
242: // same number of childrens
243:
244: boolean childrensIdentical = true;
245: for (int index = 0; index < firstChilds.getLength()
246: && childrensIdentical; index++) {
247: // Compare childrens 1-to-1
248: Element firstChild = (Element) firstChilds.item(index);
249: Element secondChild = (Element) secondChilds
250: .item(index);
251: childrensIdentical = areElementIdentical(firstChild,
252: secondChild);
253: }
254: identical &= childrensIdentical;
255: }
256: return identical;
257: }
258:
259: /**
260: * @param first first element to compare.
261: * @param second second element to compare.
262: * @return Returns <code>true</code> if both elements are identical.
263: */
264: private static boolean areElementIdentical(final Element first,
265: final Element second) {
266:
267: // Check namespace URI
268: if (!first.getNamespaceURI().equals(second.getNamespaceURI())) {
269: return false;
270: }
271:
272: // Check localname
273: if (!first.getLocalName().equals(second.getLocalName())) {
274: return false;
275: }
276:
277: return areChildNodesIdentical(first, second);
278: }
279:
280: /**
281: * Add a new security-role element into the web.xml
282: * @param securityRole A node containing the login-config setting
283: */
284: public void addSecurityRole(Node securityRole) {
285:
286: // Maybe the security-role element was already added.
287: // Look in the Document to find an pre-existing security-role element
288: // with the same name.
289:
290: Element foundSecurityRole = findSecurityRole((Element) securityRole);
291: if (foundSecurityRole == null) {
292: // no security-rople element, or none is matching
293: // we can add our own ...
294:
295: Element mySecurityRole = newJ2EEElement(SECURITY_ROLE);
296:
297: // securityRole comes from another document, therefor have to import
298: // first
299: Node importedSecurityRole = getDocument().importNode(
300: securityRole, true);
301:
302: while (importedSecurityRole.hasChildNodes()) {
303: mySecurityRole.appendChild(importedSecurityRole
304: .getFirstChild());
305: }
306:
307: // add security-role to webapp
308: getElement().appendChild(mySecurityRole);
309: }
310: // else, the right security-role is already there, nothing to do ...
311: }
312:
313: /**
314: * @param securityRole <code>security-role</code> element.
315: * @return Returns a matching <code>security-role</code> element already
316: * in the Document.
317: */
318: private Element findSecurityRole(Element securityRole) {
319:
320: NodeList potentialSecurityRoles = getElement()
321: .getElementsByTagNameNS(J2EE_NS, SECURITY_ROLE);
322: if (potentialSecurityRoles.getLength() == 0) {
323: // no security-role elements defined
324: // exit safely
325: return null;
326: }
327:
328: // Iterates over the potential security-role to find a matching
329: // role-name
330: Element found = null;
331: String requiredRoleName = getRoleName(securityRole);
332: // while nothing was found AND iteration not over
333: for (int index = 0; (index < potentialSecurityRoles.getLength())
334: && (found == null); index++) {
335: Element potentialSR = (Element) potentialSecurityRoles
336: .item(index);
337: // get the potential security-role name
338: String roleName = getRoleName(potentialSR);
339:
340: // compare, if equals, we're done
341: if (requiredRoleName.equals(roleName)) {
342: found = potentialSR;
343: }
344: }
345:
346: // found is still null if no matching security-role was found
347: return found;
348: }
349:
350: /**
351: * @param securityRole <code>security-role</code> element in which the role name
352: * will be extracted.
353: * @return Returns the extracted <code>role-name</code> value.
354: */
355: private static String getRoleName(Element securityRole) {
356: Node roleName = securityRole.getElementsByTagNameNS(J2EE_NS,
357: ROLE_NAME).item(0);
358: // j2ee:security-role/j2ee:role-name/#text
359: return roleName.getFirstChild().getNodeValue().trim();
360: }
361:
362: /**
363: * Remove a <code>servlet</code> element from the web.xml.
364: * @param name servlet name.
365: */
366: public void removeServlet(String name) {
367: Element servlet = findServlet(name);
368:
369: if (servlet != null) {
370: getElement().removeChild(servlet);
371: }
372: }
373:
374: /**
375: * Remove a <code>servlet</code> element from the web.xml.
376: * @param name servlet name.
377: * @return security-role elements for this servlet if such elements exist
378: */
379: public NodeList removeServletWithSecurity(String name) {
380: Element servlet = findServlet(name);
381: NodeList elements = null;
382:
383: if (servlet != null) {
384:
385: elements = servlet.getElementsByTagNameNS(J2EE_NS,
386: SECURITY_ROLE_REF);
387: // if the list is empty, return null
388: if (elements.getLength() == 0) {
389: elements = null;
390: }
391: getElement().removeChild(servlet);
392: }
393: return elements;
394: }
395:
396: /**
397: * Add a new <code>servlet-mapping</code> element in the web.xml.
398: * @param name servlet name.
399: * @param mapping <code>url-mapping</code> value
400: */
401: public void addServletMapping(String name, String mapping) {
402: Element servletMapping = newJ2EEElement(SERVLET_MAPPING);
403: Element servletName = newJ2EEElement(SERVLET_NAME, name);
404: Element urlMapping = newJ2EEElement(URL_MAPPING, mapping);
405:
406: servletMapping.appendChild(servletName);
407: servletMapping.appendChild(urlMapping);
408:
409: // add servletMapping in the webapp Element
410: getElement().appendChild(servletMapping);
411: }
412:
413: /**
414: * Add a new <code>init-param</code> element in the web.xml.
415: * @param servletName the servlet name where init-param will be added.
416: * @param pName parameter name
417: * @param pValue parameter value
418: */
419: public void addServletParam(String servletName, String pName,
420: String pValue) {
421: Element ip = newJ2EEElement(INIT_PARAM);
422: Element pn = newJ2EEElement(PARAM_NAME, pName);
423: Element pv = newJ2EEElement(PARAM_VALUE, pValue);
424:
425: ip.appendChild(pn);
426: ip.appendChild(pv);
427:
428: Element servlet = findServlet(servletName);
429: servlet.appendChild(ip);
430:
431: }
432:
433: /**
434: * Add a new <code>security-role-ref</code> element in the web.xml.
435: * @param servletName the servlet name where security-role-ref will be
436: * added.
437: * @param securityRoleRefs security-role elements for a servlet
438: */
439: public void addServletSecurityRoleRefs(String servletName,
440: NodeList securityRoleRefs) {
441: // find the servlet
442: Element servlet = findServlet(servletName);
443: // add all security-role-ref
444: for (int i = 0; i < securityRoleRefs.getLength(); i++) {
445: Node securityRoleRefItem = securityRoleRefs.item(i);
446: servlet.appendChild(securityRoleRefItem);
447: }
448: }
449:
450: /**
451: * search webapp element for servlet named with the given name.
452: * @param name the searched servlet name
453: * @return the found element or null if element is not found (should'nt
454: * occurs).
455: */
456: private Element findServlet(String name) {
457: NodeList nl = getElement().getElementsByTagNameNS(J2EE_NS,
458: SERVLET);
459: Element servlet = null;
460:
461: for (int i = 0; (i < nl.getLength()) && (servlet == null); i++) {
462: Element e = (Element) nl.item(i);
463:
464: NodeList names = e.getElementsByTagNameNS(J2EE_NS,
465: SERVLET_NAME);
466:
467: // test servlet/servlet-name/#text-node.value
468: if (names.item(0).getFirstChild().getNodeValue().equals(
469: name)) {
470: servlet = e;
471: }
472: }
473:
474: return servlet;
475: }
476:
477: /**
478: * Remove servlet-mapping tag associated to a given servlet-name
479: * @param sName servlet-name
480: * @return url-pattern element's value in the servelet-mapping
481: */
482: public String removeServletMapping(String sName) {
483: NodeList nl = getElement().getElementsByTagNameNS(J2EE_NS,
484: SERVLET_MAPPING);
485: Element mapping = null;
486: String urlPatternValue = null;
487:
488: for (int i = 0; (i < nl.getLength()) && (mapping == null); i++) {
489: Element e = (Element) nl.item(i);
490:
491: NodeList names = e.getElementsByTagNameNS(J2EE_NS,
492: SERVLET_NAME);
493:
494: // test servlet-mapping/servlet-name/#text-node.value
495: if (names.item(0).getFirstChild().getNodeValue().equals(
496: sName)) {
497: mapping = e;
498: }
499: }
500:
501: if (mapping != null) {
502: if (getLogger().isLoggable(BasicLevel.DEBUG)) {
503: getLogger().log(BasicLevel.DEBUG,
504: "mapping element found : " + mapping);
505: }
506: // pick up the url-pattern before removing
507: NodeList urlPatterns = mapping.getElementsByTagNameNS(
508: J2EE_NS, URL_PATTERN);
509: urlPatternValue = urlPatterns.item(0).getFirstChild()
510: .getNodeValue();
511:
512: getElement().removeChild(mapping);
513: }
514:
515: return urlPatternValue;
516: }
517:
518: /**
519: * Update the security-constraint element having url-pattern equal with
520: * oldPattern by replacing this old pattern with the newUrlPattern
521: * @param oldUrlPatter url-pattern to be replaced
522: * @param newUrlPatterValue url-pattern to replace with
523: */
524: public void updateSecurityConstraint(String oldUrlPatter,
525: String newUrlPatterValue) {
526:
527: NodeList nl = getElement().getElementsByTagNameNS(J2EE_NS,
528: SECURITY_CONSTRAINT);
529:
530: // loop over security constraints
531: for (int i = 0; i < nl.getLength(); i++) {
532: Element e = (Element) nl.item(i);
533:
534: // look at nested url-pattern Element(s)
535: NodeList urlPatternCollection = e.getElementsByTagNameNS(
536: J2EE_NS, URL_PATTERN);
537: for (int j = 0; j < urlPatternCollection.getLength(); j++) {
538:
539: Element urlPatternElement = (Element) urlPatternCollection
540: .item(j);
541: Text urlPatternText = (Text) urlPatternElement
542: .getFirstChild();
543:
544: // if found urlPattern Element, replace its value
545: if (urlPatternText.getNodeValue().equals(oldUrlPatter)) {
546: urlPatternText.setNodeValue(newUrlPatterValue);
547: }
548: }
549: }
550: }
551:
552: /**
553: * DOCUMENT ME!
554: * @param name DOCUMENT ME!
555: * @param home DOCUMENT ME!
556: * @param remote DOCUMENT ME!
557: * @param link DOCUMENT ME!
558: */
559: public void addEjbRef(String name, String home, String remote,
560: String link) {
561:
562: Element ejbRef = newJ2EEElement("ejb-ref");
563: Element ejbRefName = newJ2EEElement("ejb-ref-name", name);
564: Element ejbRefType = newJ2EEElement("ejb-ref-type", "Session");
565: Element ejbHome = newJ2EEElement("home", home);
566: Element ejbRemote = newJ2EEElement("remote", remote);
567: Element ejbLink = newJ2EEElement("ejb-link", link);
568:
569: ejbRef.appendChild(ejbRefName);
570: ejbRef.appendChild(ejbRefType);
571: ejbRef.appendChild(ejbHome);
572: ejbRef.appendChild(ejbRemote);
573: ejbRef.appendChild(ejbLink);
574:
575: getElement().appendChild(ejbRef);
576:
577: }
578:
579: /**
580: * DOCUMENT ME!
581: * @param name DOCUMENT ME!
582: * @param home DOCUMENT ME!
583: * @param remote DOCUMENT ME!
584: * @param link DOCUMENT ME!
585: */
586: public void addEjbLocalRef(String name, String home, String remote,
587: String link) {
588:
589: Element ejbRef = newJ2EEElement("ejb-local-ref");
590: Element ejbRefName = newJ2EEElement("ejb-ref-name", name);
591: Element ejbRefType = newJ2EEElement("ejb-ref-type", "Session");
592: Element ejbHome = newJ2EEElement("local-home", home);
593: Element ejbRemote = newJ2EEElement("local", remote);
594: Element ejbLink = newJ2EEElement("ejb-link", link);
595:
596: ejbRef.appendChild(ejbRefName);
597: ejbRef.appendChild(ejbRefType);
598: ejbRef.appendChild(ejbHome);
599: ejbRef.appendChild(ejbRemote);
600: ejbRef.appendChild(ejbLink);
601:
602: getElement().appendChild(ejbRef);
603:
604: }
605: }
|