OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [tools/] [gnu/] [classpath/] [tools/] [rmic/] [SourceGiopRmicCompiler.java] - Blame information for rev 779

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 779 jeremybenn
/* SourceGiopRmicCompiler -- Central GIOP-based RMI stub and tie compiler class.
2
   Copyright (C) 2006, 2008 Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
*/
21
 
22
package gnu.classpath.tools.rmic;
23
 
24
import gnu.classpath.tools.rmic.AbstractMethodGenerator;
25
 
26
import java.io.File;
27
import java.io.FileOutputStream;
28
import java.io.IOException;
29
import java.io.OutputStream;
30
import java.lang.reflect.Method;
31
import java.net.MalformedURLException;
32
import java.net.URL;
33
import java.net.URLClassLoader;
34
import java.rmi.Remote;
35
import java.rmi.RemoteException;
36
import java.util.ArrayList;
37
import java.util.Collection;
38
import java.util.Collections;
39
import java.util.Comparator;
40
import java.util.HashSet;
41
import java.util.Iterator;
42
import java.util.Properties;
43
import java.util.StringTokenizer;
44
import java.util.TreeSet;
45
 
46
/**
47
 * Provides the extended rmic functionality to generate the POA - based classes
48
 * for GIOP (javax.rmi.CORBA package).
49
 *
50
 * @author Audrius Meskauskas, Lithuania (audriusa@Bioinformatics.org)
51
 */
52
public class SourceGiopRmicCompiler
53
  extends Generator implements Comparator, RmicBackend
54
{
55
  /** The package name. */
56
  protected String packag;
57
 
58
  /**
59
   * The "basic" name (normally, the interface name, unless several Remote -
60
   * derived interfaces are implemented.
61
   */
62
  protected String name;
63
 
64
  /**
65
   * The name (without package) of the class, passed as the parameter.
66
   */
67
  protected String implName;
68
 
69
  /**
70
   * The proposed name for the stub.
71
   */
72
  protected String stubName;
73
 
74
  /**
75
   * The Remote's, implemented by this class.
76
   */
77
  protected Collection implementedRemotes = new HashSet();
78
 
79
  /**
80
   * The extra classes that must be imported.
81
   */
82
  protected Collection extraImports = new HashSet();
83
 
84
  /**
85
   * The methods we must implement.
86
   */
87
  protected Collection methods = new HashSet();
88
 
89
  /**
90
   * The map of all code generator variables.
91
   */
92
  public Properties vars = new Properties();
93
 
94
  /**
95
   * If this flag is set (true by default), the compiler generates the Servant
96
   * based classes. If set to false, the compiler generates the old style
97
   * ObjectImpl based classes.
98
   */
99
  protected boolean poaMode = true;
100
 
101
  /**
102
   * If this flag is set (true by default), the compiler emits warnings.
103
   */
104
  protected boolean warnings = true;
105
 
106
  /**
107
   * If this flag is set (false by default), the compiler does not
108
   * write output files.
109
   */
110
  protected boolean noWrite = false;
111
 
112
  /**
113
   * If this flag is set (false by default), the compiler keeps source
114
   * output files.  For SourceGiopRmicCompiler this overrides
115
   * -nowrite, since -nowrite doesn't apply to sources kept with
116
   * -keep.
117
   */
118
  protected boolean keep = false;
119
 
120
  /**
121
   * Verbose output
122
   */
123
  protected boolean verbose = false;
124
 
125
  /**
126
   * Force mode - do not check the exceptions
127
   */
128
  protected boolean force = false;
129
 
130
  /**
131
   * The output directory for generated files.
132
   */
133
  protected String outputDirectory;
134
 
135
  /**
136
   * The class loader to load the class being compiled.
137
   */
138
  ClassLoader classLoader;
139
 
140
  /**
141
   * Clear data, preparing for the next compilation.
142
   */
143
  public synchronized void reset()
144
  {
145
    packag = name = implName = stubName = null;
146
    implementedRemotes.clear();
147
    extraImports.clear();
148
    methods.clear();
149
    vars.clear();
150
  }
151
 
152
  /**
153
   * Set the class path (handle the -classpath key)
154
   *
155
   * @param classPath the class path to set.
156
   */
157
  public void setClassPath(String classPath)
158
  {
159
    classLoader = Thread.currentThread().getContextClassLoader();
160
    StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator,
161
                                              true);
162
    ArrayList urls = new ArrayList(tok.countTokens());
163
    String s = null;
164
    try
165
      {
166
        while (tok.hasMoreTokens())
167
          {
168
            s = tok.nextToken();
169
            if (s.equals(File.pathSeparator))
170
              urls.add(new File(".").toURL());
171
            else
172
              {
173
                urls.add(new File(s).toURL());
174
                if (tok.hasMoreTokens())
175
                  {
176
                    // Skip the separator.
177
                    tok.nextToken();
178
                    // If the classpath ended with a separator,
179
                    // append the current directory.
180
                    if (! tok.hasMoreTokens())
181
                      urls.add(new File(".").toURL());
182
                  }
183
              }
184
          }
185
      }
186
    catch (MalformedURLException ex)
187
      {
188
        System.err.println("Malformed path '" + s + "' in classpath '"
189
                           + classPath + "'");
190
        System.exit(1);
191
      }
192
    URL[] u = new URL[urls.size()];
193
    for (int i = 0; i < u.length; i++)
194
      {
195
        u[i] = (URL) urls.get(i);
196
      }
197
 
198
    classLoader = new URLClassLoader(u, classLoader);
199
  }
200
 
201
  /**
202
   * Loads the class with the given name (uses class path, if applicable)
203
   *
204
   * @param name the name of the class.
205
   */
206
  public Class loadClass(String name)
207
  {
208
    ClassLoader loader = classLoader;
209
    if (loader == null)
210
      loader = Thread.currentThread().getContextClassLoader();
211
    try
212
      {
213
        return loader.loadClass(name);
214
      }
215
    catch (ClassNotFoundException e)
216
      {
217
        System.err.println(name+" not found on "+loader);
218
        System.exit(1);
219
        // Unreacheable code.
220
        return null;
221
      }
222
  }
223
 
224
  /**
225
   * Compile the given class (the instance of Remote), generating the stub and
226
   * tie for it.
227
   *
228
   * @param remote
229
   *          the class to compile.
230
   */
231
  public synchronized void compile(Class remote)
232
  {
233
    reset();
234
    String s;
235
 
236
    // Get the package.
237
    s = remote.getName();
238
    int p = s.lastIndexOf('.');
239
    if (p < 0)
240
      {
241
        // Root package.
242
        packag = "";
243
        implName = name = s;
244
      }
245
    else
246
      {
247
        packag = s.substring(0, p);
248
        implName = name = s.substring(p + 1);
249
      }
250
 
251
    name = convertStubName(name);
252
 
253
    stubName = name;
254
 
255
    vars.put("#name", name);
256
    vars.put("#package", packag);
257
    vars.put("#implName", implName);
258
 
259
    if (verbose)
260
      System.out.println("Package " + packag + ", name " + name + " impl "
261
                         + implName);
262
 
263
    // Get the implemented remotes.
264
    Class[] interfaces = remote.getInterfaces();
265
 
266
    for (int i = 0; i < interfaces.length; i++)
267
      {
268
        if (Remote.class.isAssignableFrom(interfaces[i]))
269
          {
270
            if (! interfaces[i].equals(Remote.class))
271
              {
272
                implementedRemotes.add(interfaces[i]);
273
              }
274
          }
275
      }
276
 
277
    vars.put("#idList", getIdList(implementedRemotes));
278
 
279
    // Collect and process methods.
280
    Iterator iter = implementedRemotes.iterator();
281
 
282
    while (iter.hasNext())
283
      {
284
        Class c = (Class) iter.next();
285
        Method[] m = c.getMethods();
286
 
287
        // Check if throws RemoteException.
288
        for (int i = 0; i < m.length; i++)
289
          {
290
            Class[] exc = m[i].getExceptionTypes();
291
            boolean remEx = false;
292
 
293
            for (int j = 0; j < exc.length; j++)
294
              {
295
                if (exc[j].isAssignableFrom(RemoteException.class))
296
                  {
297
                    remEx = true;
298
                    break;
299
                  }
300
              }
301
            if (! remEx && !force)
302
              throw new CompilationError(m[i].getName() + ", defined in "
303
                                         + c.getName()
304
                                         + ", does not throw "
305
                                         + RemoteException.class.getName());
306
            AbstractMethodGenerator mm = createMethodGenerator(m[i]);
307
            methods.add(mm);
308
          }
309
      }
310
  }
311
 
312
  /**
313
   * Create the method generator for the given method.
314
   *
315
   * @param m the method
316
   *
317
   * @return the created method generator
318
   */
319
  protected AbstractMethodGenerator createMethodGenerator(Method m)
320
  {
321
    return new MethodGenerator(m, this);
322
  }
323
 
324
  /**
325
   * Get the name of the given class. The class is added to imports, if not
326
   * already present and not from java.lang and not from the current package.
327
   *
328
   * @param nameIt
329
   *          the class to name
330
   * @return the name of class as it should appear in java language
331
   */
332
  public synchronized String name(Class nameIt)
333
  {
334
    if (nameIt.isArray())
335
      {
336
        // Mesure dimensions:
337
        int dimension = 0;
338
        Class finalComponent = nameIt;
339
        while (finalComponent.isArray())
340
          {
341
            finalComponent = finalComponent.getComponentType();
342
            dimension++;
343
          }
344
 
345
        StringBuilder brackets = new StringBuilder();
346
 
347
        for (int i = 0; i < dimension; i++)
348
          {
349
            brackets.append("[]");
350
          }
351
 
352
        return name(finalComponent) + " " + brackets;
353
      }
354
    else
355
      {
356
        String n = nameIt.getName();
357
        if (! nameIt.isArray() && ! nameIt.isPrimitive())
358
          if (! n.startsWith("java.lang")
359
              && ! (packag != null && n.startsWith(packag)))
360
            extraImports.add(n);
361
 
362
        int p = n.lastIndexOf('.');
363
        if (p < 0)
364
          return n;
365
        else
366
          return n.substring(p + 1);
367
      }
368
  }
369
 
370
  /**
371
   * Get the RMI-style repository Id for the given class.
372
   *
373
   * @param c
374
   *          the interface, for that the repository Id must be created.
375
   * @return the repository id
376
   */
377
  public String getId(Class c)
378
  {
379
    return "RMI:" + c.getName() + ":0000000000000000";
380
  }
381
 
382
  /**
383
   * Get repository Id string array declaration.
384
   *
385
   * @param remotes
386
   *          the collection of interfaces
387
   * @return the fully formatted string array.
388
   */
389
  public String getIdList(Collection remotes)
390
  {
391
    StringBuilder b = new StringBuilder();
392
 
393
    // Keep the Ids sorted, ensuring, that the same order will be preserved
394
    // between compilations.
395
    TreeSet sortedIds = new TreeSet();
396
 
397
    Iterator iter = remotes.iterator();
398
    while (iter.hasNext())
399
      {
400
        sortedIds.add(getId((Class) iter.next()));
401
      }
402
 
403
    iter = sortedIds.iterator();
404
    while (iter.hasNext())
405
      {
406
        b.append("      \"" + iter.next() + "\"");
407
        if (iter.hasNext())
408
          b.append(", \n");
409
      }
410
    return b.toString();
411
  }
412
 
413
  /**
414
   * Generate stub. Can only be called from {@link #compile}.
415
   *
416
   * @return the string, containing the text of the generated stub.
417
   */
418
  public String generateStub()
419
  {
420
    String template = getResource("Stub.jav");
421
 
422
    // Generate methods.
423
    StringBuilder b = new StringBuilder();
424
    Iterator iter = methods.iterator();
425
    while (iter.hasNext())
426
      {
427
        AbstractMethodGenerator m = (AbstractMethodGenerator) iter.next();
428
        b.append(m.generateStubMethod());
429
      }
430
 
431
    vars.put("#stub_methods", b.toString());
432
    vars.put("#imports", getImportStatements());
433
    vars.put("#interfaces", getAllInterfaces());
434
 
435
    String output = replaceAll(template, vars);
436
    return output;
437
  }
438
 
439
  /**
440
   * Get the list of all interfaces, implemented by the class, that are
441
   * derived from Remote.
442
   *
443
   * @return the string - all interfaces.
444
   */
445
  public String getAllInterfaces()
446
  {
447
    StringBuilder b = new StringBuilder();
448
    Iterator iter = implementedRemotes.iterator();
449
 
450
    while (iter.hasNext())
451
      {
452
        b.append(name((Class) iter.next()));
453
        if (iter.hasNext())
454
          b.append(", ");
455
      }
456
 
457
    return b.toString();
458
  }
459
 
460
  /**
461
   * Generate Tie. Can only be called from {@link #compile}.
462
   *
463
   * @return the string, containing the text of the generated Tie.
464
   */
465
  public String generateTie()
466
  {
467
    String template;
468
    if (poaMode)
469
      template = getResource("Tie.jav");
470
    else
471
      template = getResource("ImplTie.jav");
472
 
473
    // Generate methods.
474
    HashFinder hashFinder = new HashFinder();
475
 
476
    // Find the hash character position:
477
    Iterator iter = methods.iterator();
478
    String[] names = new String[methods.size()];
479
    int p = 0;
480
 
481
    for (int i = 0; i < names.length; i++)
482
      names[i] = ((MethodGenerator) iter.next()).getGiopMethodName();
483
 
484
    int hashCharPosition = hashFinder.findHashCharPosition(names);
485
 
486
    iter = methods.iterator();
487
    while (iter.hasNext())
488
      ((MethodGenerator) iter.next()).hashCharPosition = hashCharPosition;
489
 
490
    vars.put("#hashCharPos", Integer.toString(hashCharPosition));
491
 
492
    ArrayList sortedMethods = new ArrayList(methods);
493
    Collections.sort(sortedMethods, this);
494
 
495
    iter = sortedMethods.iterator();
496
 
497
    StringBuilder b = new StringBuilder();
498
 
499
    MethodGenerator prev = null;
500
 
501
    while (iter.hasNext())
502
      {
503
        MethodGenerator m = (MethodGenerator) iter.next();
504
        m.previous = prev;
505
        m.hashCharPosition = hashCharPosition;
506
        prev = m;
507
        b.append(m.generateTieMethod());
508
      }
509
 
510
    vars.put("#tie_methods", b.toString());
511
 
512
    vars.put("#imports", getImportStatements());
513
 
514
    String output = replaceAll(template, vars);
515
    return output;
516
  }
517
 
518
  public int compare(Object a, Object b)
519
  {
520
    MethodGenerator g1 = (MethodGenerator) a;
521
    MethodGenerator g2 = (MethodGenerator) b;
522
 
523
    return g1.getHashChar() - g2.getHashChar();
524
  }
525
 
526
  /**
527
   * Import the extra classes, used as the method parameters and return values.
528
   *
529
   * @return the additional import block.
530
   */
531
  protected String getImportStatements()
532
  {
533
    TreeSet imp = new TreeSet();
534
 
535
    Iterator it = extraImports.iterator();
536
    while (it.hasNext())
537
      {
538
        String ic = it.next().toString();
539
        imp.add("import " + ic + ";\n");
540
      }
541
 
542
    StringBuilder b = new StringBuilder();
543
    it = imp.iterator();
544
 
545
    while (it.hasNext())
546
      {
547
        b.append(it.next());
548
      }
549
    return b.toString();
550
  }
551
 
552
  /**
553
   * If this flag is set (true by default), the compiler generates the Servant
554
   * based classes. If set to false, the compiler generates the old style
555
   * ObjectImpl based classes.
556
   */
557
  public void setPoaMode(boolean mode)
558
  {
559
    poaMode = mode;
560
  }
561
 
562
  /**
563
   * Set the verbose output mode (false by default)
564
   *
565
   * @param isVerbose the verbose output mode
566
   */
567
  public void setVerbose(boolean isVerbose)
568
  {
569
    verbose = isVerbose;
570
  }
571
 
572
  /**
573
   * If this flag is set (true by default), the compiler emits warnings.
574
   */
575
  public void setWarnings(boolean warn)
576
  {
577
    warnings = warn;
578
  }
579
 
580
  /**
581
   * Set the error ignore mode.
582
   */
583
  public void setForce(boolean isforce)
584
  {
585
    force = isforce;
586
  }
587
 
588
  /**
589
   * Get the package name.
590
   */
591
  public String getPackageName()
592
  {
593
    return packag;
594
  }
595
 
596
  /**
597
   * Get the proposed stub name
598
   */
599
  public String getStubName()
600
  {
601
    return stubName;
602
  }
603
 
604
  /**
605
   * Additional processing of the stub name.
606
   */
607
  public String convertStubName(String name)
608
  {
609
    // Drop the Impl suffix, if one exists.
610
    if (name.endsWith("Impl"))
611
      return name.substring(0, name.length() - "Impl".length());
612
    else
613
      return name;
614
  }
615
 
616
  /**
617
   * Assumes that output directory is already created.
618
   */
619
  protected boolean outputTie(File fw, Class c)
620
  {
621
    try
622
      {
623
        String tie = generateTie();
624
        String tieName = "_" + name(c) + "_Tie.java";
625
 
626
        OutputStream out = new FileOutputStream(new File(fw, tieName));
627
        out.write(tie.getBytes());
628
        out.close();
629
      }
630
    catch (IOException ioex)
631
      {
632
        System.err.println("Output path not accessible");
633
        ioex.printStackTrace();
634
        return false;
635
      }
636
    return true;
637
  }
638
 
639
  public void setup(boolean keep, boolean need11Stubs, boolean need12Stubs,
640
                    boolean iiop, boolean poa, boolean debug, boolean warnings,
641
                    boolean noWrite, boolean verbose, boolean force, String classpath,
642
                    String bootclasspath, String extdirs, String outputDirectory)
643
  {
644
    setWarnings(warnings);
645
    setVerbose(verbose);
646
    setForce(force);
647
    setClassPath(classpath);
648
    setPoaMode(poa);
649
    this.outputDirectory = outputDirectory;
650
    this.noWrite = noWrite;
651
    this.keep = keep;
652
  }
653
 
654
  public boolean run(String[] inputFiles)
655
  {
656
    for (int i = 0; i < inputFiles.length; i++)
657
      {
658
        reset();
659
        Class c = loadClass(inputFiles[i]);
660
 
661
        compile(c);
662
        String packag = getPackageName().replace('.', '/');
663
        File fw = new File(outputDirectory, packag);
664
 
665
        // Generate stub.
666
        String stub = generateStub();
667
        String subName = getStubName() + "_Stub.java";
668
 
669
        // -keep overrides -nowrite for sources.
670
        if (!noWrite || keep)
671
          {
672
            try
673
              {
674
                fw.mkdirs();
675
                OutputStream out = new FileOutputStream(new File(fw,
676
                                                                 subName));
677
                out.write(stub.getBytes());
678
                out.close();
679
 
680
                // Generate tie
681
                if (!outputTie(fw, c))
682
                  return false;
683
              }
684
            catch (IOException ioex)
685
              {
686
                System.err.println("Output path not accessible");
687
                ioex.printStackTrace();
688
                return false;
689
              }
690
          }
691
      }
692
    return true;
693
  }
694
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.