001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.diff;
034:
035: import java.util.*;
036:
037: import org.apache.oro.text.perl.*;
038:
039: import com.jeantessier.text.*;
040:
041: public class ListDiffPrinter {
042: public static final boolean DEFAULT_COMPRESS = false;
043: public static final String DEFAULT_ENCODING = "utf-8";
044: public static final String DEFAULT_DTD_PREFIX = "http://depfind.sourceforge.net/dtd";
045:
046: private static final Perl5Util perl = new Perl5Util();
047:
048: private PrinterBuffer buffer = new PrinterBuffer();
049:
050: private boolean compress;
051:
052: private String name = "";
053: private String oldVersion = "";
054: private String newVersion = "";
055: private Collection<String> removed = new TreeSet<String>();
056: private Collection<String> added = new TreeSet<String>();
057:
058: public ListDiffPrinter() {
059: this (DEFAULT_COMPRESS, DEFAULT_ENCODING, DEFAULT_DTD_PREFIX);
060: }
061:
062: public ListDiffPrinter(boolean compress) {
063: this (compress, DEFAULT_ENCODING, DEFAULT_DTD_PREFIX);
064: }
065:
066: public ListDiffPrinter(String encoding, String dtdPrefix) {
067: this (DEFAULT_COMPRESS, encoding, dtdPrefix);
068: }
069:
070: public ListDiffPrinter(boolean compress, String encoding,
071: String dtdPrefix) {
072: this .compress = compress;
073:
074: appendHeader(encoding, dtdPrefix);
075: }
076:
077: public void setIndentText(String indentText) {
078: buffer.setIndentText(indentText);
079: }
080:
081: private void appendHeader(String encoding, String dtdPrefix) {
082: append("<?xml version=\"1.0\" encoding=\"").append(encoding)
083: .append("\" ?>").eol();
084: eol();
085: append("<!DOCTYPE list-diff SYSTEM \"").append(dtdPrefix)
086: .append("/list-diff.dtd\">").eol();
087: eol();
088: }
089:
090: public String getName() {
091: return name;
092: }
093:
094: public void setName(String name) {
095: this .name = name;
096: }
097:
098: public String getOldVersion() {
099: return oldVersion;
100: }
101:
102: public void setOldVersion(String oldVersion) {
103: this .oldVersion = oldVersion;
104: }
105:
106: public String getNewVersion() {
107: return newVersion;
108: }
109:
110: public void setNewVersion(String newVersion) {
111: this .newVersion = newVersion;
112: }
113:
114: public Collection<String> getRemoved() {
115: return Collections.unmodifiableCollection(removed);
116: }
117:
118: public void remove(String line) {
119: this .removed.add(line);
120: }
121:
122: public Collection<String> getAdded() {
123: return Collections.unmodifiableCollection(added);
124: }
125:
126: public void add(String line) {
127: this .added.add(line);
128: }
129:
130: protected ListDiffPrinter append(boolean b) {
131: buffer.append(b);
132: return this ;
133: }
134:
135: protected ListDiffPrinter append(char c) {
136: buffer.append(c);
137: return this ;
138: }
139:
140: protected ListDiffPrinter append(char[] str, int offset, int len) {
141: buffer.append(str, offset, len);
142: return this ;
143: }
144:
145: protected ListDiffPrinter append(char[] str) {
146: buffer.append(str);
147: return this ;
148: }
149:
150: protected ListDiffPrinter append(double d) {
151: buffer.append(d);
152: return this ;
153: }
154:
155: protected ListDiffPrinter append(float f) {
156: buffer.append(f);
157: return this ;
158: }
159:
160: protected ListDiffPrinter append(int i) {
161: buffer.append(i);
162: return this ;
163: }
164:
165: protected ListDiffPrinter append(long l) {
166: buffer.append(l);
167: return this ;
168: }
169:
170: protected ListDiffPrinter append(Object obj) {
171: buffer.append(obj);
172: return this ;
173: }
174:
175: protected ListDiffPrinter append(String str) {
176: buffer.append(str);
177: return this ;
178: }
179:
180: protected ListDiffPrinter indent() {
181: buffer.indent();
182: return this ;
183: }
184:
185: protected ListDiffPrinter eol() {
186: buffer.eol();
187: return this ;
188: }
189:
190: protected void raiseIndent() {
191: buffer.raiseIndent();
192: }
193:
194: protected void lowerIndent() {
195: buffer.lowerIndent();
196: }
197:
198: public String toString() {
199: indent().append("<list-diff>").eol();
200: raiseIndent();
201:
202: indent().append("<name>").append(getName()).append("</name>")
203: .eol();
204: indent().append("<old>").append(getOldVersion()).append(
205: "</old>").eol();
206: indent().append("<new>").append(getNewVersion()).append(
207: "</new>").eol();
208:
209: indent().append("<removed>").eol();
210: raiseIndent();
211: printLines(compress ? compress(getRemoved()) : getRemoved());
212: lowerIndent();
213: indent().append("</removed>").eol();
214:
215: indent().append("<added>").eol();
216: raiseIndent();
217: printLines(compress ? compress(getAdded()) : getAdded());
218: lowerIndent();
219: indent().append("</added>").eol();
220:
221: lowerIndent();
222: indent().append("</list-diff>").eol();
223:
224: return buffer.toString();
225: }
226:
227: private void printLines(Collection<String> lines) {
228: for (String line : lines) {
229: int pos = line.lastIndexOf(" [");
230: if (pos != -1) {
231: indent().append("<line>")
232: .append(line.substring(0, pos)).append(
233: "</line>").eol();
234: } else {
235: indent().append("<line>").append(line)
236: .append("</line>").eol();
237: }
238: }
239: }
240:
241: private Collection<String> compress(Collection<String> lines) {
242: Collection<String> result = new TreeSet<String>();
243:
244: for (String line : lines) {
245: boolean add = true;
246: if (line.endsWith(" [C]")) {
247: String packageName = extractPackageName(line);
248:
249: add = !lines.contains(packageName + " [P]");
250: } else if (line.endsWith(" [F]")) {
251: String className = extractClassName(line);
252: String packageName = extractPackageName(className);
253:
254: add = !lines.contains(packageName + " [P]")
255: && !lines.contains(className + " [C]");
256: }
257:
258: if (add) {
259: result.add(line);
260: }
261: }
262:
263: return result;
264: }
265:
266: private String extractPackageName(String className) {
267: String result = "";
268:
269: int pos = className.lastIndexOf('.');
270: if (pos != -1) {
271: result = className.substring(0, pos);
272: }
273:
274: return result;
275: }
276:
277: private String extractClassName(String featureName) {
278: String result = "";
279:
280: synchronized (perl) {
281: if (perl.match("/^(.*)\\.[^\\.]*\\(.*\\)/", featureName)) {
282: result = perl.group(1);
283: } else if (perl.match("/^(.*)\\.[\\^.]*/", featureName)) {
284: result = perl.group(1);
285: }
286: }
287:
288: return result;
289: }
290: }
|