KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > orb > ParsedIOR


1 package org.jacorb.orb;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1997-2004 Gerald Brose.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */

22
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.*;
26
27 import org.jacorb.orb.iiop.*;
28 import org.jacorb.orb.util.CorbaLoc;
29
30 import org.apache.avalon.framework.logger.Logger;
31
32 import org.jacorb.util.ObjectUtil;
33 import org.omg.CONV_FRAME.CodeSetComponentInfo;
34 import org.omg.CONV_FRAME.CodeSetComponentInfoHelper;
35 import org.omg.CosNaming.*;
36 import org.omg.GIOP.*;
37 import org.omg.IOP.*;
38 import org.omg.ETF.*;
39
40 /**
41  * Class to convert IOR strings into IOR structures
42  *
43  * @author Gerald Brose, FU Berlin
44  * @version $Id: ParsedIOR.java,v 1.64 2004/10/21 14:55:58 francisco Exp $
45  */

46
47 public class ParsedIOR
48 {
49     //for byte -> hexchar
50
private static final char[] lookup =
51     new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
52
53     private Profile effectiveProfile = null;
54     private List profiles = new ArrayList();
55
56     /** top-level tagged components, i.e. NOT part of IOP components. Other
57      * tagged components may be part of the profile bodies
58      */

59     private TaggedComponentList components = new TaggedComponentList();
60
61     protected boolean endianness = false;
62     private String JavaDoc ior_str = null;
63     private IOR ior = null;
64
65     private ORB orb = null;
66
67     private CodeSetComponentInfo cs_info = null;
68     private Integer JavaDoc orbTypeId = null;
69     private Logger logger;
70
71     /* static part */
72
73     /**
74      * factory method
75      */

76
77     public static IOR createObjectIOR(org.omg.ETF.Profile profile)
78     {
79         String JavaDoc repId = "IDL:omg.org/CORBA/Object:1.0";
80         TaggedComponentList components = new TaggedComponentList();
81
82         CDROutputStream orbIDComponentDataStream = new CDROutputStream();
83         orbIDComponentDataStream.beginEncapsulatedArray();
84         orbIDComponentDataStream.write_long(ORBConstants.JACORB_ORB_ID);
85         components.addComponent
86         (
87             new TaggedComponent
88             (
89                 TAG_ORB_TYPE.value,
90                 orbIDComponentDataStream.getBufferCopy()
91             )
92         );
93
94         List taggedProfileList = new ArrayList();
95         TaggedProfileHolder tp = new TaggedProfileHolder();
96         TaggedComponentSeqHolder tcs = new TaggedComponentSeqHolder();
97         tcs.value = components.asArray();
98
99         profile.marshal(tp, tcs);
100         taggedProfileList.add(tp.value);
101
102         // copy the profiles into the IOR
103

104         TaggedProfile[] tps = new TaggedProfile[taggedProfileList.size()];
105         taggedProfileList.toArray(tps);
106
107         return new IOR(repId, tps);
108     }
109
110     /**
111     * This method replaces the unfiyTargetAddress method.
112     * <P>
113     * It will extract an object key from any given GIOP::TargetAddress
114     * assuming an appropriate ETF::Factories implementation is availble
115     * for the profile in use.
116     */

117     public static byte[] extractObjectKey(TargetAddress addr, ORB orb)
118     {
119         TaggedProfile tp = null;
120         switch (addr.discriminator())
121         {
122             case KeyAddr.value:
123                 return addr.object_key();
124             case ProfileAddr.value:
125                 tp = new TaggedProfile(addr.profile().tag, addr.profile().profile_data);
126                 break;
127             case ReferenceAddr.value:
128                 IORAddressingInfo info = addr.ior();
129                 tp = new TaggedProfile(info.ior.profiles[info.selected_profile_index].tag,
130                                        info.ior.profiles[info.selected_profile_index].profile_data);
131                 break;
132         }
133         TaggedProfileHolder profile = new TaggedProfileHolder(tp);
134         org.omg.ETF.Factories profileFactory = orb.getTransportManager().getFactories(tp.tag);
135         if (profileFactory != null)
136         {
137             return profileFactory.demarshal_profile(profile, new TaggedComponentSeqHolder()).get_object_key();
138         }
139         return null;
140     }
141
142     /**
143      * Returns the value of the TAG_JAVA_CODEBASE component from this IOR,
144      * or null if no such component exists. The component is first searched
145      * in the effective profile, if that is an IIOPProfile, and failing that,
146      * in the MULTIPLE_COMPONENTS list.
147      */

148     public String JavaDoc getCodebaseComponent()
149     {
150         return getStringComponent (TAG_JAVA_CODEBASE.value);
151     }
152
153     /**
154      * Creates a new <code>ParsedIOR</code> instance.
155      *
156      * @param object_reference a <code>String</code> value
157      * @param orb an <code>org.omg.CORBA.ORB</code> value
158      * @exception IllegalArgumentException if an error occurs
159      */

160
161     public ParsedIOR( String JavaDoc object_reference, org.omg.CORBA.ORB JavaDoc orb, Logger logger)
162         throws IllegalArgumentException JavaDoc
163     {
164         if (orb instanceof ORB)
165         {
166             this.orb = (org.jacorb.orb.ORB)orb;
167             parse( object_reference );
168         }
169         else
170         {
171             throw new IllegalArgumentException JavaDoc
172                 ("Construct ParsedIOR with full ORB not Singleton");
173         }
174         this.logger = logger;
175     }
176
177     /**
178      * Creates a new <code>ParsedIOR</code> instance.
179      *
180      * @param object_reference a <code>String</code> value
181      * @param orb an <code>org.jacorb.orb.ORB</code> value
182      * @exception IllegalArgumentException if an error occurs
183      */

184     public ParsedIOR( String JavaDoc object_reference, ORB orb, Logger logger )
185         throws IllegalArgumentException JavaDoc
186     {
187         this.orb = orb;
188         this.logger = logger;
189         parse( object_reference );
190     }
191
192     public ParsedIOR( IOR _ior, org.jacorb.orb.ORB orb, Logger logger )
193     {
194         this.orb = orb;
195         this.logger = logger;
196         decode( _ior );
197     }
198
199     public boolean equals( Object JavaDoc o )
200     {
201         return o instanceof ParsedIOR &&
202             ((ParsedIOR) o).ior_str.equals( ior_str );
203     }
204
205     /**
206      * When multiple internet IOP tags are present, they will probably
207      * have different versions, we will use the highest version
208      * between 0 and 1.
209      */

210     public void decode( IOR _ior )
211     {
212         for( int i = 0; i < _ior.profiles.length; i++ )
213         {
214             int tag = _ior.profiles[i].tag;
215
216             switch( tag )
217             {
218                 case TAG_MULTIPLE_COMPONENTS.value :
219                 {
220                     components = new TaggedComponentList
221                                            (_ior.profiles[i].profile_data);
222                     break;
223                 }
224                 default:
225                 {
226                     org.omg.ETF.Factories f =
227                         orb.getTransportManager().getFactories (tag);
228                     if (f != null)
229                     {
230                         TaggedProfileHolder tp =
231                             new TaggedProfileHolder (_ior.profiles[i]);
232                         profiles.add
233                             (f.demarshal_profile
234                                 (tp,
235                                  new TaggedComponentSeqHolder()));
236                     }
237                     else
238                     {
239                         if (logger.isDebugEnabled())
240                             logger.debug("No transport available for profile tag " + tag);
241                     }
242                     break;
243                 }
244             }
245         }
246
247         effectiveProfile =
248             orb.getTransportManager().getProfileSelector().selectProfile (profiles,
249                                                                           orb.getClientConnectionManager());
250         ior = _ior;
251         ior_str = getIORString();
252
253         if( effectiveProfile != null )
254         {
255             cs_info = (CodeSetComponentInfo)getComponent(TAG_CODE_SETS.value,
256                                                          CodeSetComponentInfoHelper.class);
257             orbTypeId = getLongComponent (TAG_ORB_TYPE.value);
258         }
259     }
260
261     public CodeSetComponentInfo getCodeSetComponentInfo()
262     {
263         return cs_info;
264     }
265
266     public Integer JavaDoc getORBTypeId()
267     {
268         return orbTypeId;
269     }
270
271     public IOR getIOR()
272     {
273         return ior;
274     }
275
276     public String JavaDoc getIORString()
277     {
278         if( ior_str == null )
279         {
280             try
281             {
282                 CDROutputStream out = new CDROutputStream( orb );
283                 out.beginEncapsulatedArray();
284
285                 IORHelper.write(out,ior);
286
287                 byte bytes[] = out.getBufferCopy();
288
289                 StringBuffer JavaDoc sb = new StringBuffer JavaDoc("IOR:");
290
291                 for (int j = 0; j < bytes.length; j++)
292                 {
293                     sb.append( lookup[ (bytes[j] >> 4) & 0xF ] );
294                     sb.append( lookup[ (bytes[j] ) & 0xF ] );
295                 }
296
297                 ior_str = sb.toString();
298             }
299             catch (Exception JavaDoc e)
300             {
301                 if (logger.isErrorEnabled())
302                     logger.error(e.getMessage());
303                 throw new org.omg.CORBA.UNKNOWN JavaDoc("Error in building IIOP-IOR");
304             }
305         }
306
307         return ior_str;
308     }
309
310     public byte[] get_object_key()
311     {
312         return effectiveProfile.get_object_key();
313     }
314
315     public List getProfiles()
316     {
317         return profiles;
318     }
319
320     public Profile getEffectiveProfile()
321     {
322         return effectiveProfile;
323     }
324
325     public String JavaDoc getTypeId()
326     {
327         return ior.type_id;
328     }
329
330     public String JavaDoc getIDString ()
331     {
332         StringBuffer JavaDoc buff = new StringBuffer JavaDoc(getTypeId ());
333         buff.append (":");
334         byte[] key = get_object_key ();
335
336         for (int j = 0; j < key.length; j++)
337         {
338             buff.append(lookup [(key[j] >> 4) & 0xF]);
339             buff.append(lookup [(key[j] ) & 0xF]);
340         }
341
342         return (buff.toString ());
343     }
344
345     public TaggedComponentList getMultipleComponents()
346     {
347         return components;
348     }
349
350     public boolean isNull()
351     {
352         return ior.type_id.equals("") && ior.profiles.length == 0;
353     }
354
355     /**
356      * <code>parse</code> decodes the object_reference passed to ParsedIOR.
357      *
358      * @param object_reference a <code>String</code> value.
359      * @exception IllegalArgumentException if object_reference is null or the
360      * designated resource cannot be found.
361      */

362     protected void parse(String JavaDoc object_reference)
363         throws IllegalArgumentException JavaDoc
364     {
365         if (object_reference == null)
366         {
367             throw new IllegalArgumentException JavaDoc("Null object reference");
368         }
369
370         if (object_reference.startsWith("IOR:"))
371         {
372             parse_stringified_ior(object_reference);
373         }
374         else if (object_reference.startsWith("corbaloc:"))
375         {
376             parse_corbaloc(object_reference);
377         }
378         else if (object_reference.startsWith("corbaname:"))
379         {
380             parse_corbaname(object_reference);
381         }
382         else if (object_reference.startsWith("resource:"))
383         {
384             parse_resource(object_reference.substring(9));
385         }
386         else if (object_reference.startsWith("jndi:"))
387         {
388             parse_jndi(object_reference.substring(5));
389         }
390         else
391         {
392             if (logger.isDebugEnabled())
393                 logger.debug("Trying to resolve URL/IOR from: " + object_reference);
394
395             String JavaDoc content = null;
396             try
397             {
398                 content = ObjectUtil.readURL(object_reference);
399             }
400             catch(java.io.IOException JavaDoc ioe)
401             {
402                 if (logger.isDebugEnabled())
403                     logger.debug("Error reading IOR/URL: ", ioe);
404                 // ignore;
405
}
406             if (content == null)
407             {
408                 throw new IllegalArgumentException JavaDoc("Invalid or unreadable URL/IOR: " + object_reference);
409             }
410             parse(content);
411         }
412         ior_str = getIORString();
413     }
414
415     // parser helper methods
416

417     private void parse_stringified_ior(String JavaDoc object_reference)
418     {
419         ByteArrayOutputStream JavaDoc bos = new ByteArrayOutputStream JavaDoc();
420         int cnt = (object_reference.length() - 4) / 2;
421         for (int j = 0; j < cnt; j++)
422         {
423             char c1 = object_reference.charAt(j * 2 + 4);
424             char c2 = object_reference.charAt(j * 2 + 5);
425             int i1 =
426                 (c1 >= 'a')
427                     ? (10 + c1 - 'a')
428                     : ((c1 >= 'A') ? (10 + c1 - 'A') : (c1 - '0'));
429             int i2 =
430                 (c2 >= 'a')
431                     ? (10 + c2 - 'a')
432                     : ((c2 >= 'A') ? (10 + c2 - 'A') : (c2 - '0'));
433             bos.write((i1 * 16 + i2));
434         }
435
436         CDRInputStream in_ = null;
437
438         if (orb == null)
439         {
440             in_ =
441                 new CDRInputStream(org.omg.CORBA.ORB.init(), bos.toByteArray());
442         }
443         else
444         {
445             in_ = new CDRInputStream(orb, bos.toByteArray());
446         }
447
448         endianness = in_.read_boolean();
449         if (endianness)
450         {
451             in_.setLittleEndian(true);
452         }
453
454         IOR _ior = IORHelper.read(in_);
455         decode(_ior);
456     }
457
458     private void parse_corbaloc(String JavaDoc object_reference)
459     {
460         CorbaLoc corbaLoc = new CorbaLoc(orb, object_reference);
461         IOR ior = null;
462         if (corbaLoc.rir())
463         {
464             try
465             {
466                 org.omg.CORBA.Object JavaDoc obj =
467                     orb.resolve_initial_references(corbaLoc.getKeyString());
468
469                 if (obj == null)
470                 {
471                     throw new IllegalArgumentException JavaDoc(
472                         "Unable to resolve reference for "
473                             + corbaLoc.getKeyString());
474                 }
475
476                 ior =
477                     ((Delegate) ((org.omg.CORBA.portable.ObjectImpl JavaDoc)obj)._get_delegate()).getIOR();
478             }
479             catch (Exception JavaDoc e)
480             {
481                 if (logger.isErrorEnabled())
482                     logger.error(e.getMessage());
483                 throw new IllegalArgumentException JavaDoc("Invalid corbaloc: URL");
484             }
485         }
486         else
487         {
488             Profile profile = corbaLoc.profileList[0];
489             if (profile == null)
490                 return; // could not decode any address in list
491

492             profile.set_object_key(corbaLoc.getKey());
493             ior = createObjectIOR(profile);
494         }
495
496         decode(ior);
497     }
498
499     private void parse_corbaname(String JavaDoc object_reference)
500     {
501         String JavaDoc corbaloc = "corbaloc:";
502         String JavaDoc name = "";
503         int colon = object_reference.indexOf(':');
504         int pound = object_reference.indexOf('#');
505
506         if (pound == -1)
507             corbaloc += object_reference.substring(colon + 1);
508         else
509         {
510             corbaloc += object_reference.substring(colon + 1, pound);
511             name = object_reference.substring(pound + 1);
512         }
513
514         /* empty key string in corbaname becomes NameService */
515         if (corbaloc.indexOf('/') == -1)
516             corbaloc += "/NameService";
517
518         if (logger.isDebugEnabled())
519             logger.debug(corbaloc);
520
521         try
522         {
523             NamingContextExt n =
524                 NamingContextExtHelper.narrow(orb.string_to_object(corbaloc));
525             IOR ior = null;
526             // If the name hasn't been set - which is possible if we're just
527
// resolving the root context down try to use name.
528
if (name.length() > 0)
529             {
530                 org.omg.CORBA.Object JavaDoc target = n.resolve_str(name);
531                 ior =
532                     ((Delegate) ((org.omg.CORBA.portable.ObjectImpl JavaDoc)target)
533                         ._get_delegate())
534                         .getIOR();
535             }
536             else
537             {
538                 ior =
539                     ((Delegate) ((org.omg.CORBA.portable.ObjectImpl JavaDoc)n)
540                         ._get_delegate())
541                         .getIOR();
542             }
543             decode(ior);
544         }
545         catch (Exception JavaDoc e)
546         {
547             if (logger.isErrorEnabled())
548                 logger.error(e.getMessage());
549             throw new IllegalArgumentException JavaDoc("Invalid object reference: " +
550                                                object_reference);
551         }
552     }
553
554     private void parse_resource(String JavaDoc resourceName)
555     {
556         if (logger.isDebugEnabled())
557             logger.debug("Trying to resolve URL/IOR from resource: " + resourceName);
558
559         ClassLoader JavaDoc cl = getClass().getClassLoader();
560         if (cl == null)
561         {
562             cl = ClassLoader.getSystemClassLoader();
563         }
564
565         URL JavaDoc url = cl.getResource(resourceName);
566         if (url == null)
567         {
568             throw new IllegalArgumentException JavaDoc(
569                 "Failed to get resource: " + resourceName);
570         }
571
572         String JavaDoc content = null;
573         try
574         {
575             ObjectUtil.readURL(url.toString());
576         }
577         catch( java.io.IOException JavaDoc ioe )
578         {
579             // ignore
580
}
581
582         if (content == null)
583         {
584             throw new IllegalArgumentException JavaDoc("Failed to read resource: " +
585                                                resourceName);
586         }
587         parse(content);
588     }
589
590     private void parse_jndi(String JavaDoc jndiName)
591     {
592         if (logger.isDebugEnabled())
593             logger.debug("Trying to resolve JNDI/IOR from name: " + jndiName);
594
595         java.lang.Object JavaDoc obj = null;
596         try
597         {
598             // javax.naming.Context initialContext =
599
// new javax.naming.InitialContext ();
600
// obj = initialContext.lookup (jndiName);
601

602             // Replaced lines above with reflected equivalent so will compile
603
// under JDK < 1.3 which do not include javax.naming classes. For
604
// jndi based name resolution to work obviously javax.naming
605
// classes must be in CLASSPATH.
606
//
607
Class JavaDoc[] types = new Class JavaDoc[1];
608             java.lang.Object JavaDoc[] params = new java.lang.Object JavaDoc[1];
609
610             Class JavaDoc cls = ObjectUtil.classForName("javax.naming.InitialContext");
611             java.lang.Object JavaDoc initialContext = cls.newInstance();
612
613             types[0] = String JavaDoc.class;
614             params[0] = jndiName;
615
616             java.lang.reflect.Method JavaDoc method = cls.getMethod("lookup", types);
617             obj = method.invoke(initialContext, params);
618         }
619         catch (Exception JavaDoc ex)
620         {
621             throw new IllegalArgumentException JavaDoc(
622                 "Failed to lookup JNDI/IOR: " + ex);
623         }
624
625         if (obj == null)
626         {
627             throw new IllegalArgumentException JavaDoc("Null JNDI/IOR: " + jndiName);
628         }
629         parse(obj.toString());
630     }
631
632     /**
633      * Returns the component with the given tag, searching the effective
634      * profile's components first (this is only possible with org.jacorb.orb.etf.ProfileBase implementations),
635      * and then the MULTIPLE_COMPONENTS profile, if one exists. If no
636      * component with the given tag exists, this method returns null.
637      */

638     private Object JavaDoc getComponent (int tag, Class JavaDoc helper)
639     {
640         Object JavaDoc result = null;
641         if (effectiveProfile instanceof org.jacorb.orb.etf.ProfileBase)
642             // TODO Should there be a component access mechanism for all
643
// ETF profiles? Clarify with OMG.
644
result = ((org.jacorb.orb.etf.ProfileBase)effectiveProfile).getComponent (tag, helper);
645
646         if (result != null)
647             return result;
648         else
649             return components.getComponent (tag, helper);
650     }
651
652     private static class LongHelper
653     {
654         public static Integer JavaDoc read (org.omg.CORBA.portable.InputStream JavaDoc in)
655         {
656             return new Integer JavaDoc (in.read_long());
657         }
658     }
659
660     /**
661      * Works like getComponent(), but for component values of CORBA type long.
662      */

663     private Integer JavaDoc getLongComponent (int tag)
664     {
665         return (Integer JavaDoc)getComponent (tag, LongHelper.class);
666     }
667
668     private static class StringHelper
669     {
670         public static String JavaDoc read (org.omg.CORBA.portable.InputStream JavaDoc in)
671         {
672             return new String JavaDoc (in.read_string());
673         }
674     }
675     
676     /**
677      * Works like getComponent(), but for component values of type string.
678      */

679     private String JavaDoc getStringComponent (int tag)
680     {
681         return (String JavaDoc)getComponent (tag, StringHelper.class);
682     }
683
684     /**
685      * <code>isParsableProtocol</code> returns true if ParsedIOR can handle the
686      * protocol within the string.
687      *
688      * @param check a <code>String</code> a string containing a protocol.
689      * @return a <code>boolean</code> denoting whether ParsedIOR can handle this
690      * protocol
691      */

692     public static boolean isParsableProtocol( String JavaDoc check )
693     {
694         if (check.startsWith( "IOR:" ) ||
695             check.startsWith( "corbaloc:" ) ||
696             check.startsWith( "corbaname:" ) ||
697             check.startsWith( "resource:" ) ||
698             check.startsWith( "jndi:" ) ||
699             check.startsWith( "file:" ) ||
700             check.startsWith( "http:" )
701            )
702         {
703             return true;
704         }
705         else
706         {
707             return false;
708         }
709     }
710 }
711
Popular Tags