KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > google > gwt > dev > shell > StandardRebindOracle


1 /*
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */

16 package com.google.gwt.dev.shell;
17
18 import com.google.gwt.core.ext.PropertyOracle;
19 import com.google.gwt.core.ext.TreeLogger;
20 import com.google.gwt.core.ext.UnableToCompleteException;
21 import com.google.gwt.core.ext.typeinfo.JClassType;
22 import com.google.gwt.core.ext.typeinfo.TypeOracle;
23 import com.google.gwt.dev.cfg.Rule;
24 import com.google.gwt.dev.cfg.Rules;
25 import com.google.gwt.dev.cfg.StaticPropertyOracle;
26 import com.google.gwt.dev.jdt.CacheManager;
27 import com.google.gwt.dev.jdt.RebindOracle;
28 import com.google.gwt.dev.util.Util;
29
30 import java.io.File JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.HashSet JavaDoc;
33 import java.util.Iterator JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Set JavaDoc;
36
37 /**
38  * Implements rebind logic in terms of a variety of other well-known oracles.
39  */

40 public class StandardRebindOracle implements RebindOracle {
41
42   /**
43    * Makes the actual deferred binding decision by examining rules.
44    */

45   private final class Rebinder {
46
47     private final StandardGeneratorContext genCtx;
48
49     private final Set JavaDoc usedRules = new HashSet JavaDoc();
50
51     private final List JavaDoc usedTypeNames = new ArrayList JavaDoc();
52
53     public Rebinder(TypeOracle typeOracle, PropertyOracle propOracle) {
54       genCtx = new StandardGeneratorContext(typeOracle, propOracle, genDir,
55           outDir, cacheManager);
56     }
57
58     public String JavaDoc rebind(TreeLogger logger, String JavaDoc typeName)
59         throws UnableToCompleteException {
60
61       String JavaDoc result = tryRebind(logger, typeName);
62       if (result == null) {
63         result = typeName;
64       }
65
66       // Announce the newly-generated types.
67
//
68
JClassType[] genTypes = genCtx.finish(logger);
69       if (genTypes.length > 0) {
70         onGeneratedTypes(result, genTypes);
71       }
72
73       return result;
74     }
75
76     private String JavaDoc tryRebind(TreeLogger logger, String JavaDoc typeName)
77         throws UnableToCompleteException {
78       if (usedTypeNames.contains(typeName)) {
79         // Found a cycle.
80
//
81
String JavaDoc[] cycle = (String JavaDoc[]) Util.toArray(String JavaDoc.class, usedTypeNames);
82         Messages.UNABLE_TO_REBIND_DUE_TO_CYCLE_IN_RULES.log(logger, cycle, null);
83         throw new UnableToCompleteException();
84       }
85
86       // Remember that we've seen this one.
87
//
88
usedTypeNames.add(typeName);
89
90       // Make the rebind decision.
91
//
92
if (rules.isEmpty()) {
93         logger.log(TreeLogger.DEBUG,
94             "No rules are defined, so no substitution can occur", null);
95         return null;
96       }
97
98       for (Iterator JavaDoc iter = rules.iterator(); iter.hasNext();) {
99         Rule rule = (Rule) iter.next();
100
101         // Branch the logger.
102
//
103
TreeLogger branch = Messages.TRACE_CHECKING_RULE.branch(logger, rule,
104             null);
105
106         if (rule.isApplicable(branch, genCtx, typeName)) {
107           // See if this rule has already been used. This is needed to prevent
108
// infinite loops with 'when-assignable' conditions.
109
//
110
if (!usedRules.contains(rule)) {
111             usedRules.add(rule);
112             Messages.TRACE_RULE_MATCHED.log(logger, null);
113
114             // Invoke the rule.
115
//
116
return rule.realize(logger, genCtx, typeName);
117
118           } else {
119             // We are skipping this rule because it has already been used
120
// in a previous iteration.
121
//
122
}
123         } else {
124           Messages.TRACE_RULE_DID_NOT_MATCH.log(logger, null);
125         }
126       }
127
128       // No matching rule for this type.
129
//
130
return null;
131     }
132   }
133
134   private final CacheManager cacheManager;
135
136   private final File JavaDoc genDir;
137
138   private final File JavaDoc outDir;
139
140   private final PropertyOracle propOracle;
141
142   private final Rules rules;
143
144   private final TypeOracle typeOracle;
145
146   public StandardRebindOracle(TypeOracle typeOracle, PropertyOracle propOracle,
147       Rules rules, File JavaDoc genDir, File JavaDoc moduleOutDir, CacheManager cacheManager) {
148     this.typeOracle = typeOracle;
149     this.propOracle = propOracle;
150     this.rules = rules;
151     this.genDir = genDir;
152     this.outDir = moduleOutDir;
153     if (cacheManager != null) {
154       this.cacheManager = cacheManager;
155     } else {
156       this.cacheManager = new CacheManager(typeOracle);
157     }
158   }
159
160   public StandardRebindOracle(TypeOracle typeOracle,
161       StaticPropertyOracle propOracle, Rules rules, File JavaDoc genDir,
162       File JavaDoc moduleOutDir) {
163     // This is a path used for non-hosted mode execution; therefore no caching.
164
this(typeOracle, propOracle, rules, genDir, moduleOutDir, null);
165   }
166
167   public String JavaDoc rebind(TreeLogger logger, String JavaDoc typeName)
168       throws UnableToCompleteException {
169
170     logger = Messages.TRACE_TOPLEVEL_REBIND.branch(logger, typeName, null);
171
172     Rebinder rebinder = new Rebinder(typeOracle, propOracle);
173     String JavaDoc result = rebinder.rebind(logger, typeName);
174
175     Messages.TRACE_TOPLEVEL_REBIND_RESULT.log(logger, result, null);
176
177     return result;
178   }
179
180   protected void onGeneratedTypes(String JavaDoc result, JClassType[] genTypes) {
181   }
182
183 }
184
Popular Tags