KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > JSX > Config


1 /** ===========================================================================
2     * Config
3     * ======
4     * Send this into the constructor, instead of long and complex argument lists.
5     * We thus extend the JSX API without polluting the JOS API.
6     * Use the same for both ObjOut (serialization) and ObjIn (deserialization).
7     * Less elegant, and redundant; but simpler to write, maintain and use.
8     *
9     * C++ style for setters enables this usage:
10     * Config c = new Config().aliasesUsed(true).IDsUsed(true);
11     *
12     * Nice: to design to serialize to XML nicely. For example:
13     * Sub-sets of functionality would have their own object.
14     * Config c = (Config) JSX.ObjIn(new FileReader("cyclicConfig.jsx"));
15     **/

16
17 package JSX;
18
19 public class Config {
20     public Config() {} //because default visibility is packageVersion(true);
21

22 /** Refactor - used by ObjIn, for mapping class and package names.
23     * Implementations of Refactor avail: ClassRefactor
24     * (You can also make your own implementation).
25 **/

26     public Refactor refactor = null;
27     public Config setRefactor(Refactor refactor) {
28         this.refactor = refactor;
29         return this;
30     }
31
32
33 /** ObjIn - fields missing from classes.
34     * Handling NoSuchFieldExceptions:
35     * This handles fields in XML which are not found in the class.
36     * NOTE: This prevents putFields from working - we could avoid this problem
37     * by requiring persistentSerialFields, and returning these with the
38     * getAllFields.
39     * Q: if I define persistentSerialFields, does that make all other fields
40     * transient?
41     **/

42     //CONSIDER: a better (read: less verbose) name for this?
43
public NoSuchFieldHandler noSuchFieldHandler;
44     public Config setNoSuchFieldHandler(NoSuchFieldHandler noSuchFieldHandler) {
45         this.noSuchFieldHandler = noSuchFieldHandler;
46         return this;
47     }
48
49 //ObjOut - formatting
50
//Gil Peeter's compact "no formatting" (no unnec whitespace, all one line)
51
public boolean formatted = true; //easy test
52
public Config setFormatted(boolean formatted) {
53         this.formatted = formatted;
54         return this;
55     }
56
57 //ObjOut - superVersion
58
public boolean superVersion = false; //by default
59
public Config superVersion(boolean superVersion) {
60         this.superVersion = superVersion;
61         return this;
62     }
63
64 //ObjIn - import, XSLT stylesheet preprocess - filename
65
public String JavaDoc importFile; //Data object - do not change name!
66
//Is an external type (memento) better for parameter passing? We can edit
67
//the implementation without changing the external representation. Or, if
68
//change is needed, instead editing the external type, to make a new one
69
//altogether (with a different name). Type safety automatically insures
70
//code is written to handle this new external type.
71
//Consider that a common informal technique might be to place all the
72
//data into a "data object" (stamping?), and send that. This amounts to
73
//an informal external type, and might not have all the advantages of the
74
//full method mentioned here.
75
public Config importFile(String JavaDoc importFile) {
76         this.importFile = importFile;
77         return this;
78     }
79
80 //ObjOut - export, XSLT stylesheet postprocess - filename
81
//Not yet implemented
82
/*
83     public String exportFile;
84     public Config exportFile(String exportFile) {
85         this.exportFile = exportFile;
86         return this;
87     }
88 */

89
90
91 //ObjOut - aliases - this works from the constructor switch. Show
92
// *rewire* so that it is controlled from here instead.
93
/*
94     public boolean areAliasesUsed;
95     public Config aliasesUsed(boolean areAliasesUsed) {
96         this.areAliasesUsed = areAliasesUsed;
97         return this;
98     }
99 */

100
101 //ObjOut - ID's - this really should be implemented...
102
//Note: if this is switched on, then all Strings will be rendered as
103
//elements, instead of as attributes, so that their ID can be stated.
104
// NEED: to standardize this config object!
105
// (1). Strings are rendered as tags (never as attributes)
106
// (2). an "alias-ID" attribute is included with every object tag
107
// - NOT: null, alias-ref, classes within uper, opt-data nor prim-opt data.
108
// public boolean aliasID = true; // for testing only
109
public boolean aliasID = false; // off by default, because cleaner XML
110
public Config aliasID(boolean aliasID) {
111         this.aliasID = aliasID;
112         return this;
113     }
114
115
116 // DTDGenerator
117
// ------------
118
//JSX is now configured with a DTDGenerator. This requires creating the
119
//DTDGenerator, including it's Writer (same as for ObjOut).
120
//This might not be the best architecture, but at least it keeps it simple,
121
//so not too hard to understand, maintain and changet later on...
122

123 //If ObjOut is configured with DTDwriter set (ie non-null), then each
124
//object-graph written will generate its corresponding DTD to that writer.
125

126 //JSX does some inference - rather than account for all 5000+ possible standard
127
//classes, and all your application classes, JSX instead assumes that the
128
//objects you write out are representative, and there is at least one
129
//instance object of each class that you will ever want to write out.
130
// NB: This means that you had better ensure that the object graph you use
131
// to generate the DTD does indeed includes instances of all the classes
132
// you will ever be interested in.
133

134 //Particular usage note:
135
//If want to write several object graphs, but only need one DTD, you should
136
//construct a second ObjOut without a DTDwriter.
137

138 //Future work:
139
//It may be better to allow several object graphs to be written, to give the
140
//best chance of all the classes being included (ie gain not just a
141
//representative sample, but a comprehensive, definitive one).
142
// Option 1: Write the DTD after seeing several graphs, but how to trigger it?
143
// It could be the out.close(), but this feels confusing
144
// Option 2: We could just append to the old DTD. Because there is no
145
// header information, they can be joined seamlessly. All that is
146
// required is that we don't duplicate information. This could be
147
// tricky, as we use the class list on both sides (as ELEMENTS
148
// and field content...). Solution is to track where we are up to
149
// in the list. **NO** won't work: because the earlier ELEMENTS
150
// won't know that their content could include the later classes...
151
//
152
// A nicer final option may be to make the DTD be produced *instead* of the
153
//XML. It depends on how it is used - and in practice, the overhead of
154
//producing the XML is trivial, since making DTD's is typically a one-off
155
//process. It just doesn't matter, although it would be "nice". The real
156
//goal is to make it *simple* for what needs to be done, and avoiding confusion.
157

158 //Future work:
159
//An alternative is for JSX to enable you to explicitly specify which classes
160
//you are interested in, instead of JSX gathering this information from the
161
//object graph. Perhaps the most convenient would be a combination, as it is
162
//easy to omit a class which is included (eg indirectly).
163

164 //The real danger of explicit specification is omitting the objects that
165
//a class's fields would typically reference... we could infer these from
166
//the types of those fields, but it is a risky business - very easy to omit
167
//some.
168

169 // ------NOT IMPLEMENTED AS AT: 2 March 2002--------
170
//public DTDGenerator dtdGenerator = null; //good better naming convention?
171
public DTDGenerator dtdGenerator = null;
172     public Config setDTDGenerator(DTDGenerator dtdGenerator) {
173         this.dtdGenerator = dtdGenerator;
174         return this;
175     }
176 /*
177     public Config setDTDwriter(java.io.Writer DTDwriter) {
178         this.DTDwriter = DTDwriter;
179         return this;
180     }
181 */

182
183 /** "autoMemento" means that if a class declares an inner memento, then
184     * any serialized classes it encounters will have their names changed to
185     * be the memento. In this way, a Memento can be retrofitted, to enable
186     * an old version to be read by a new version, even though the implementation
187     * have evolved, and the old version didn't declare a Memento.
188     **/

189     public boolean autoMemento = true; // for testing
190
public Config setAutoMemento(boolean autoMemento) {
191         this.autoMemento = autoMemento;
192         return this; // for chaining
193
}
194 }
195
196
Popular Tags