001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: JNDIAdapter.java,v 1.3 2007-10-19 10:35:46 sinisa Exp $
022: */
023:
024: package org.enhydra.util;
025:
026: import java.util.Hashtable;
027: import java.util.StringTokenizer;
028: import java.util.Vector;
029:
030: import javax.naming.Context;
031: import javax.naming.InitialContext;
032: import javax.naming.NameClassPair;
033: import javax.naming.NamingEnumeration;
034: import javax.naming.NamingException;
035:
036: import com.lutris.util.KeywordValueException;
037:
038: /**
039: * This class is used for reading configuration parameters using JNDI. It
040: * coresponds between InitialContext object and application's Config and
041: * ConfigFile object.
042: *
043: * @author Tanja Jovanovic
044: * @version 1.0
045: */
046: public class JNDIAdapter {
047:
048: /**
049: * Passed as the "count" argument to getInts, getLongs(), etc. to
050: * indicate that all available elements are to be retrieved.
051: */
052: // private static final int GET_ALL = -1;
053: /**
054: * Context
055: */
056: private Context context = null;
057: private Context envCtx = null;
058:
059: /**
060: * Absolute path to application configuration file.
061: */
062: public final static String FILE_JNDI_ABS_PATH_NAME = "fileJndiAbsPathName";
063:
064: /**
065: * Application component Context environment.
066: */
067: public final static String CONTEXT_FOR_ENV_BIND = "contextForEnvToBind";
068:
069: /**
070: * Default constructor for empty adapter.
071: */
072: public JNDIAdapter() {
073: try {
074: context = new InitialContext();
075: } catch (NamingException ex) {
076: // System.err.println("Error in creating initial context");
077: context = null;
078: }
079:
080: try {
081: envCtx = (Context) context.lookup("java:comp/env");
082: } catch (NamingException ex) {
083: // System.err.println("Error in creating J2EE environment of initial context");
084: envCtx = null;
085:
086: }
087: // try {
088: // for (NamingEnumeration e = envCtx.list(""); e.hasMore();) {
089: // String str = (String)e.next();
090: // System.err.println("elem= "+str);
091: // } // for
092: // }
093: // catch (NamingException ex){
094: // System.err.println("Error in creating initial context 2");
095: // ex.printStackTrace();
096: // }
097:
098: /*
099: Context ccc = null;
100: try {
101: ccc = (Context)context.lookup("java:comp/env");
102: if (ccc != null)
103: System.err.println("ccc pronadjen= " + ccc.getClass().toString());
104: else
105: System.err.println("ccc nije pronadjen!!!");
106: }
107: catch (NamingException ex){
108: System.err.println("Error in creating initial context 2");
109: ex.printStackTrace();
110: }
111:
112: try {
113: NamingEnumeration ne = ccc.listBindings("");
114: if (ne.hasMore())
115: System.err.println("hasMore" );
116: else
117: System.err.println("not hasMore ");
118: }
119: catch (NamingException ex){
120: System.err.println("Error in creating initial context 2");
121: ex.printStackTrace();
122: }
123: */
124:
125: /*
126: Context ccc = null;
127: try {
128: ccc = (Context)context.lookup("java:comp/env");
129: if (ccc != null)
130: System.err.println("ccc pronadjen= " + ccc.getClass().toString());
131: else
132: System.err.println("ccc nije pronadjen!!!");
133: }
134: catch (NamingException ex){
135: System.err.println("Error in creating initial context 2");
136: ex.printStackTrace();
137: }
138:
139: if (ccc != null){
140: try {
141: Object ppp = ccc.lookup("probaTest");
142: if (ppp != null)
143: System.err.println("ppp pronadjen= " + ppp.toString());
144: else
145: System.err.println("ppp nije pronadjen!!!");
146: }
147: catch (NamingException ex){
148: System.err.println("Error in creating initial context 4");
149: ex.printStackTrace();
150: }
151: }
152:
153: try {
154: Object o = context.lookup("java:comp/env/probaTest");
155: if (o != null)
156: System.err.println("obj2 pronadjen= " + o.toString());
157: else
158: System.err.println("obj2 nije pronadjen!!!");
159: }
160: catch (NamingException ex){
161: System.err.println("Error in creating initial context 3");
162: }
163: */
164:
165: /*
166: try {
167: Object o = context.lookup("vrati_se");
168: if (o != null)
169: System.err.println("vrati_se pronadjen!!! " + o.toString());
170: else
171: System.err.println("vrati_se nije pronadjen!!!");
172: }
173: catch (NamingException ex){
174: System.err.println("Error in creating initial context 2");
175: }
176: try {
177: Object o = context.lookup("tanja");
178: if (o != null)
179: System.err.println("tanja pronadjena!!! " + o.toString());
180: else
181: System.err.println("tanja nije pronadjena!!!");
182: }
183: catch (NamingException ex){
184: System.err.println("Error in creating initial context 3");
185: }
186: */
187: }
188:
189: /**
190: * Constructor with defined file. This is used if file other than web.xml is
191: * used for reading Application's parameters with JNDI.
192: *
193: * @param fileAbsolutePath absolute file path.
194: * @param factoryClass InitialContextFactory class used for creating
195: * application InitialContext.
196: */
197: public JNDIAdapter(String fileAbsolutePath, String factoryClass) {
198: boolean toCompileFile = false;
199: try {
200: if ((factoryClass != null) && (!factoryClass.equals(""))) {
201: Hashtable env = new Hashtable();
202: env.put(Context.INITIAL_CONTEXT_FACTORY, factoryClass);
203: context = new InitialContext(env);
204: toCompileFile = true;
205: } else {
206: System.err
207: .println("Warning: InitialContextFactory class not defined. Default will be used.");
208: context = new InitialContext();
209: }
210: } catch (NamingException ex) {
211: // System.err.println("Error in creating initial context");
212: context = null;
213: }
214: try {
215: envCtx = (Context) context.lookup("java:comp/env");
216: } catch (NamingException ex) {
217: // System.err.println("Error in creating J2EE environment of initial context");
218: envCtx = null;
219: }
220:
221: try {
222: if (toCompileFile) {
223: context.rebind(CONTEXT_FOR_ENV_BIND, envCtx);
224: context.rebind(FILE_JNDI_ABS_PATH_NAME,
225: fileAbsolutePath);
226: }
227: } catch (Exception ex) {
228: System.err.println("Error in creating JNDIAdapter(String)");
229: //ex.printStackTrace();
230: }
231:
232: }
233:
234: /**
235: * Returns <code>true</code> if the specified key is found,
236: * <code>false</code> otherwise.
237: * @param key The key whose existence is to be tested.
238: * @return <code>true</code> if the key was found, otherwise <code>false</code>.
239: */
240: public boolean containsKey(String key) {
241: try {
242: if (envCtx.lookup(key) != null)
243: return true;
244: } catch (Exception ex) {
245: }
246:
247: try {
248: if (envCtx.lookup(key + "[]") != null)
249: return true;
250: else
251: return false;
252: } catch (Exception ex) {
253: return false;
254: }
255: }
256:
257: /**
258: * Get the keywords in the table. This is only the keywords at the top
259: * level, its doesn't recurse.
260: *
261: * @return An string array of the keywords.
262: */
263: public synchronized String[] keys() {
264: Vector keyList = null;
265: try {
266: if (context != null) {
267: NamingEnumeration enumeration = envCtx.list("");
268: if ((enumeration != null) && (enumeration.hasMore())) {
269: keyList = new Vector();
270: String toAdd = null;
271: for (NamingEnumeration en = enumeration; en
272: .hasMore();) {
273: toAdd = ((NameClassPair) en.next()).getName();
274: keyList.addElement(toAdd);
275: } // for
276: }
277: }
278: // else
279: // System.err.println("enumeration == null");
280: } catch (NamingException ex) {
281: System.err.println("Error in keys() method");
282: //ex.printStackTrace();
283: keyList = null;
284: }
285:
286: String[] keyStrings = null;
287: if (keyList != null) {
288: keyStrings = new String[keyList.size()];
289: for (int idx = 0; idx < keyList.size(); idx++) {
290: keyStrings[idx] = (String) keyList.elementAt(idx);
291: }
292: }
293: return keyStrings;
294: }
295:
296: /**
297: * Recursively get the keywords for the entire table. This returns the
298: * full keyword of all leaf values.
299: *
300: * @return An string array of the keywords.
301: */
302: public synchronized String[] leafKeys() {
303: NamingEnumeration keyEnum = null;
304: Vector keyList = new Vector();
305: try {
306: keyEnum = envCtx.list("");
307: } catch (NamingException ex) {
308: System.err.println("Error in leafKeys() method");
309: //ex.printStackTrace();
310: keyEnum = null;
311: }
312: try {
313: if ((keyEnum != null) && (keyEnum.hasMore())) {
314: while (keyEnum.hasMore()) {
315: String key = ((NameClassPair) keyEnum.next())
316: .getName();
317: Object value = envCtx.lookup(key);
318: if (value != null) {
319: if (implements ContextInterface(value)) {
320: String[] subKeys = leafKeysInternal((Context) value);
321: for (int idx = 0; idx < subKeys.length; idx++) {
322: keyList.addElement(key + "/"
323: + subKeys[idx]);
324: }
325: } else {
326: keyList.addElement(key);
327: }
328: }
329: }
330: }
331: } catch (NamingException ex) {
332: System.err.println("Error occured in leafKeys() method");
333: //ex.printStackTrace();
334: keyList = null;
335: }
336: if (keyList != null) {
337: String[] keyStrings = new String[keyList.size()];
338: for (int idx = 0; idx < keyList.size(); idx++) {
339: keyStrings[idx] = (String) keyList.elementAt(idx);
340: }
341: return keyStrings;
342: }
343: return null;
344: }
345:
346: private synchronized String[] leafKeysInternal(Context con) {
347: NamingEnumeration keyEnum = null;
348: Vector keyList = new Vector();
349: try {
350: keyEnum = con.list("");
351: } catch (NamingException ex) {
352: System.err.println("Error in leafKeys() method");
353: //ex.printStackTrace();
354: keyEnum = null;
355: }
356: try {
357: if ((keyEnum != null) && (keyEnum.hasMore())) {
358: while (keyEnum.hasMore()) {
359: String key = ((NameClassPair) keyEnum.next())
360: .getName();
361: Object value = con.lookup(key);
362: if (value != null) {
363: if (implements ContextInterface(value)) {
364: String[] subKeys = leafKeysInternal((Context) value);
365: for (int idx = 0; idx < subKeys.length; idx++) {
366: keyList.addElement(key + "/"
367: + subKeys[idx]);
368: }
369: } else {
370: keyList.addElement(key);
371: }
372: }
373: }
374: }
375: } catch (NamingException ex) {
376: System.err.println("Error occured in leafKeys() method");
377: //ex.printStackTrace();
378: keyList = null;
379: }
380: if (keyList != null) {
381: String[] keyStrings = new String[keyList.size()];
382: for (int idx = 0; idx < keyList.size(); idx++) {
383: keyStrings[idx] = (String) keyList.elementAt(idx);
384: }
385: return keyStrings;
386: }
387: return null;
388: }
389:
390: /**
391: * Get the value of a field as an object.
392: *
393: * @param keyword The keyword of the field. This can be a simple keyword
394: * or a recursive, dot-seperated keyword path.
395: * @return The object value or null if its not found.
396: * @exception KeywordValueException If the keyword is not syntactically
397: * legal or is a non-leaf element of the keyword is not a section.
398: */
399: public synchronized Object get(String keyword)
400: throws NamingException {
401: Object obj = null;
402: try {
403: obj = envCtx.lookup(keyword);
404: } catch (Exception ex) {
405: obj = null;
406: }
407: if (obj != null)
408: return obj;
409: else {
410: return envCtx.lookup(keyword + "[]");
411: }
412: }
413:
414: /**
415: * Get the value of a field as an object, return a default if it
416: * does not exist.
417: *
418: * @param keyword The keyword of the field. This can be a simple keyword
419: * or a recursive, dot-seperated keyword path.
420: * @param defaultValue The default value to return it the keyword does not
421: * exist.
422: * @return The object value or <CODE>defaultValue</CODE> if its not found.
423: * @exception KeywordValueException If the keyword is not syntactically
424: * legal or is a non-leaf element of the keyword is not a section.
425: */
426: public synchronized Object get(String keyword, Object defaultValue)
427: throws NamingException {
428: Object value = null;
429: try {
430: value = get(keyword);
431: } catch (Exception e) {
432: value = null;
433: }
434: if (value == null) {
435: return defaultValue;
436: }
437: return value;
438: }
439:
440: public synchronized Object getResource(String jndiName)
441: throws NamingException {
442: Object obj = null;
443: try {
444: obj = context.lookup(jndiName);
445: } catch (Exception ex) {
446: obj = null;
447: // ex.printStackTrace();
448: }
449: if (obj == null) {
450: try {
451: obj = envCtx.lookup(jndiName);
452: } catch (Exception ex) {
453: obj = null;
454: // ex.printStackTrace();
455: }
456: }
457: return obj;
458: }
459:
460: /**
461: * Sets the value of a field with the defined key.
462: *
463: * @param keyword The keyword of the field.
464: * @param value The new field value.
465: */
466: public synchronized void set(String keyword, String value) {
467: if (envCtx != null) {
468: try {
469: envCtx.rebind(keyword, value);
470: } catch (NamingException ex) {
471: //ex.printStackTrace();
472: }
473: } else {
474: // should not happen
475: // TODO create envContext
476: }
477: }
478:
479: /**
480: * Removes field with the defined key.
481: *
482: * @param keyword The keyword of the field.
483: */
484: public synchronized void remove(String keyword) {
485: if (envCtx != null) {
486: try {
487: envCtx.unbind(keyword);
488: } catch (NamingException ex) {
489: //System.err.println("Unbind error in remove method of JNDIApadter");
490: }
491: }
492: }
493:
494: /**
495: * Converts to a string.
496: *
497: * @return Generate a string representation of this object.
498: */
499: /*
500: public synchronized String toString () {
501: // TODO
502: // return hashTable.toString();
503: return null;
504:
505: }
506: */
507:
508: /**
509: * Checks whether the object obj implements interface <code>javax.naming.Context</code>.
510: *
511: * @param obj Object for wich is checked whether is implementation of
512: * <code>javax.naming.Context</code> interface.
513: * @return true if object obj implements interface <code>javax.naming.Context</code>,
514: * otherwise false.
515: */
516: private static boolean implements ContextInterface(Object obj) {
517: Class[] interfaces = obj.getClass().getInterfaces();
518: int length = interfaces.length;
519: int i = 0;
520: while (i < length) {
521: if (interfaces[i].getName().equals("javax.naming.Context"))
522: return true;
523: i++;
524: }
525: return false;
526: }
527:
528: /**
529: * From Context String (delimiters are <code>/</code> signs) makes Config
530: * String (delimiters are <code>.</code> signs).
531: *
532: * @param oldString Context String
533: * @return Transformed Config String.
534: */
535: public static String makeConfigString(String oldString) {
536: if (oldString == null)
537: return null;
538: String newString = null;
539: newString = oldString.replaceAll("/", ".");
540: return newString;
541: }
542:
543: /**
544: * From Config String (delimiters are <code>.</code> signs) makes Context
545: * String (delimiters are <code>/</code> signs).
546: *
547: * @param oldString Config String
548: * @return Transformed Context String.
549: */
550: public static String makeContextString(String oldString) {
551: if (oldString == null)
552: return null;
553: // String newString = null;
554: StringBuffer newStringBuffer = null;
555: int len = oldString.length();
556: if (len > 0)
557: newStringBuffer = new StringBuffer("");
558: for (int i = 0; i < len; i++) {
559: char ch = oldString.charAt(i);
560: if (ch == '.') {
561: newStringBuffer.append("/");
562: } else {
563: newStringBuffer.append(ch);
564: }
565: }
566: if (newStringBuffer != null)
567: return newStringBuffer.toString();
568: else
569: return null;
570: }
571:
572: /**
573: * From String array makes String in which are String array elements
574: * separated with <code>,</code> sign.
575: *
576: * @param strings String array.
577: * @return Transformed String.
578: */
579: public static String makeStringFromStrings(String[] strings) {
580: if (strings == null)
581: return null;
582: StringBuffer newStringBuffer = null;
583: int len = strings.length;
584: if (len > 0)
585: newStringBuffer = new StringBuffer(strings[0].trim());
586: if (len > 1) {
587: for (int i = 1; i < len; i++) {
588: String str = strings[i].trim();
589: newStringBuffer.append("," + str);
590: }
591: }
592: if (newStringBuffer != null)
593: return newStringBuffer.toString();
594: else
595: return null;
596: }
597:
598: /**
599: * Returns <code>true</code> if key has indicator that the field is array
600: * (the key ends with "[]")
601: *
602: * @param key The keyword of the field.
603: * @return <code>true</code> if key has indicator that the field is array,
604: * otherwise false.
605: */
606: public static boolean isArray(String key) {
607: int len = key.length();
608: if (len < 3)
609: return false;
610: if (key.substring(len - 2).equals("[]"))
611: return true;
612: else
613: return false;
614: }
615:
616: /**
617: * Removes array indicator (the key ends with "[]") if exists.
618: *
619: * @param key The keyword of the field.
620: * @return Keyword without "[]".
621: */
622: public String removeArrayMark(String key) {
623: if (isArray(key)) {
624: int len = key.length();
625: return key.substring(0, len - 2);
626: } else
627: return null;
628: }
629:
630: /**
631: * Get the value of a field as String array.
632: *
633: * @param key The keyword of the field. This can be a simple keyword
634: * or a recursive, dot-seperated keyword path.
635: * @return The object value as String[] or null if its not found.
636: */
637: public String[] getStrings(String key) {
638: try {
639: Object returnObject = get(key);
640: if (returnObject.getClass().isArray()) {
641: return (String[]) returnObject;
642: }
643: String oldValue = (String) returnObject;
644: StringTokenizer tok = new StringTokenizer(oldValue, ",");
645: String[] newValue = new String[tok.countTokens()];
646: int i = 0;
647: while (tok.hasMoreTokens()) {
648: newValue[i] = tok.nextToken().trim();
649: i++;
650: }
651: return newValue;
652: } catch (Exception e) {
653: //e.printStackTrace();
654: System.err
655: .println("Error in getStrings() method of JNDIAdapter.");
656: return null;
657: }
658: }
659:
660: }
|