1
/* ========================================================================
2
* JCommon : a free general purpose class library for the Java(tm) platform
3
* ========================================================================
5
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
7
* Project Info: http://www.jfree.org/jcommon/index.html
9
* This library is free software; you can redistribute it and/or modify it
10
* under the terms of the GNU Lesser General Public License as published by
11
* the Free Software Foundation; either version 2.1 of the License, or
12
* (at your option) any later version.
14
* This library is distributed in the hope that it will be useful, but
15
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17
* License for more details.
19
* You should have received a copy of the GNU Lesser General Public
20
* License along with this library; if not, write to the Free Software
21
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
24
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25
* in the United States and other countries.]
27
* -------------------------
28
* SplittingModelWriter.java
29
* -------------------------
30
* (C)opyright 2003, by Thomas Morgner and Contributors.
32
* Original Author: Thomas Morgner;
33
* Contributor(s): David Gilbert (for Object Refinery Limited);
35
* $Id: SplittingModelWriter.java,v 1.2 2005/10/18 13:32:20 mungady Exp $
38
* -------------------------
39
* 12.11.2003 : Initial version
43
package org.jfree.xml.generator;
45
import java.io.BufferedWriter;
47
import java.io.FileOutputStream;
48
import java.io.IOException;
49
import java.io.OutputStreamWriter;
50
import java.util.ArrayList;
51
import java.util.Arrays;
52
import java.util.Iterator;
54
import org.jfree.io.IOUtils;
55
import org.jfree.util.HashNMap;
56
import org.jfree.util.Log;
57
import org.jfree.xml.generator.model.ClassDescription;
58
import org.jfree.xml.generator.model.DescriptionModel;
59
import org.jfree.xml.generator.model.ManualMappingInfo;
60
import org.jfree.xml.generator.model.MappingModel;
61
import org.jfree.xml.generator.model.MultiplexMappingInfo;
62
import org.jfree.xml.util.ClassModelTags;
65
* A model writer that writes to multiple files.
67
public class SplittingModelWriter extends ModelWriter {
70
private HashNMap classDescriptionByPackage;
73
private ArrayList sources;
75
/** The target file. */
76
private File targetFile;
78
/** The file extension. */
79
private String extension;
81
/** The plain file name. */
82
private String plainFileName;
85
private HashNMap manualMappingByPackage;
88
private HashNMap multiplexMappingByPackage;
91
* Creates a new instance.
93
public SplittingModelWriter() {
98
* Writes the model to the specified target.
100
* @param target the target file name.
102
* @throws IOException if there is an I/O problem.
104
public synchronized void write(final String target) throws IOException {
106
final DescriptionModel model = getModel();
107
this.sources = new ArrayList(Arrays.asList(model.getSources()));
108
this.targetFile = new File(target);
109
this.plainFileName = IOUtils.getInstance().stripFileExtension(this.targetFile.getName());
110
this.extension = IOUtils.getInstance().getFileExtension(target);
112
// split into classDescriptionByPackage ...
113
this.classDescriptionByPackage = new HashNMap();
114
for (int i = 0; i < model.size(); i++) {
115
final ClassDescription cd = model.get(i);
116
if (cd.getSource() == null) {
117
final String packageName = getPackage(cd.getObjectClass());
118
final String includeFileName = this.plainFileName + "-" + packageName
120
this.classDescriptionByPackage.add(includeFileName, cd);
123
this.classDescriptionByPackage.add(cd.getSource(), cd);
127
final MappingModel mappingModel = model.getMappingModel();
129
// split manual mappings into packages ...
130
final ManualMappingInfo[] manualMappings = mappingModel.getManualMapping();
131
this.manualMappingByPackage = new HashNMap();
132
for (int i = 0; i < manualMappings.length; i++) {
133
final ManualMappingInfo mapping = manualMappings[i];
134
if (mapping.getSource() == null) {
135
this.manualMappingByPackage.add("", mapping);
138
this.manualMappingByPackage.add(mapping.getSource(), mapping);
142
// split manual mappings into packages ...
143
final MultiplexMappingInfo[] multiplexMappings = mappingModel.getMultiplexMapping();
144
this.multiplexMappingByPackage = new HashNMap();
145
for (int i = 0; i < multiplexMappings.length; i++) {
146
final MultiplexMappingInfo mapping = multiplexMappings[i];
147
if (mapping.getSource() == null) {
148
this.multiplexMappingByPackage.add("", mapping);
151
this.multiplexMappingByPackage.add(mapping.getSource(), mapping);
156
final Object[] keys = this.classDescriptionByPackage.keySet().toArray();
157
for (int i = 0; i < keys.length; i++) {
159
final String includeFileName = (String) keys[i];
160
// write if not contained in the master file ...
161
if (!includeFileName.equals("")) {
162
writePackageFile(includeFileName);
168
this.manualMappingByPackage = null;
169
this.multiplexMappingByPackage = null;
170
this.classDescriptionByPackage = null;
175
* Writes a file for a package.
177
* @param includeFileName the name of the file.
179
* @throws IOException if there is an I/O problem.
181
private void writePackageFile(final String includeFileName) throws IOException {
183
final Iterator values = this.classDescriptionByPackage.getAll(includeFileName);
184
final Iterator manualMappings = this.manualMappingByPackage.getAll(includeFileName);
185
final Iterator multiplexMappings = this.multiplexMappingByPackage.getAll(includeFileName);
186
if (!values.hasNext() && !manualMappings.hasNext() && !multiplexMappings.hasNext()) {
190
Log.debug ("Writing included file: " + includeFileName);
191
// the current file need no longer be included manually ...
192
this.sources.remove(includeFileName);
194
final BufferedWriter writer = new BufferedWriter(
195
new OutputStreamWriter(
196
new FileOutputStream(
197
new File(this.targetFile.getParentFile(), includeFileName)
203
writeXMLHeader(writer);
204
writeStandardComment(writer, getModel().getModelComments());
205
getWriterSupport().writeTag(writer, ClassModelTags.OBJECTS_TAG);
207
while (values.hasNext()) {
208
final ClassDescription cd = (ClassDescription) values.next();
209
writeClassDescription(writer, cd);
213
while (manualMappings.hasNext()) {
214
final ManualMappingInfo mi = (ManualMappingInfo) manualMappings.next();
215
writeManualMapping(writer, mi);
218
while (multiplexMappings.hasNext()) {
219
final MultiplexMappingInfo mi = (MultiplexMappingInfo) multiplexMappings.next();
220
writeMultiplexMapping(writer, mi);
223
writeCloseComment(writer, getModel().getModelComments());
224
getWriterSupport().writeCloseTag(writer, ClassModelTags.OBJECTS_TAG);
229
* Returns the name of the package for the given class. This is a
230
* workaround for the classloader behaviour of JDK1.2.2 where no
231
* package objects are created.
233
* @param c the class for which we search the package.
235
* @return the name of the package, never null.
237
public static String getPackage(final Class c) {
238
final String className = c.getName();
239
final int idx = className.lastIndexOf('.');
241
// the default package
245
return className.substring(0, idx);
250
* Writes the master file.
252
* @throws IOException if there is an I/O problem.
254
private void writeMasterFile() throws IOException {
256
Log.debug ("Writing master file: " + this.targetFile);
258
final BufferedWriter writer = new BufferedWriter(
259
new OutputStreamWriter(new FileOutputStream(this.targetFile), "UTF-8")
262
writeXMLHeader(writer);
263
writeStandardComment(writer, getModel().getModelComments());
264
getWriterSupport().writeTag(writer, ClassModelTags.OBJECTS_TAG);
266
for (int i = 0; i < this.sources.size(); i++) {
267
final String includeFileName = (String) this.sources.get(i);
268
if (!includeFileName.equals("")) {
269
writeTag(writer, ClassModelTags.INCLUDE_TAG, ClassModelTags.SOURCE_ATTR,
270
includeFileName, getModel().getIncludeComment(includeFileName));
274
final Object[] keys = this.classDescriptionByPackage.keySet().toArray();
276
for (int i = 0; i < keys.length; i++) {
277
final String includeFileName = (String) keys[i];
278
if (!includeFileName.equals("")) {
279
writeTag(writer, ClassModelTags.INCLUDE_TAG, ClassModelTags.SOURCE_ATTR,
280
includeFileName, getModel().getIncludeComment(includeFileName));
284
final Iterator values = this.classDescriptionByPackage.getAll("");
285
while (values.hasNext()) {
286
final ClassDescription cd = (ClassDescription) values.next();
287
writeClassDescription(writer, cd);
290
final Iterator manualMappings = this.manualMappingByPackage.getAll("");
291
while (manualMappings.hasNext()) {
292
final ManualMappingInfo mi = (ManualMappingInfo) manualMappings.next();
293
writeManualMapping(writer, mi);
296
final Iterator multiplexMappings = this.multiplexMappingByPackage.getAll("");
297
while (multiplexMappings.hasNext()) {
298
final MultiplexMappingInfo mi = (MultiplexMappingInfo) multiplexMappings.next();
299
writeMultiplexMapping(writer, mi);
302
writeCloseComment(writer, getModel().getModelComments());
303
getWriterSupport().writeCloseTag(writer, ClassModelTags.OBJECTS_TAG);