1
2
3
4
5
6
7
8
9
10
11
12
13 package gov.nasa.pds.ltdt.label.reformat;
14
15 import gov.nasa.pds.ltdt.label.statement.PrettyAttributeStatement;
16 import gov.nasa.pds.ltdt.label.statement.PrettyCommentStatement;
17 import gov.nasa.pds.ltdt.label.statement.PrettyGroupStatement;
18 import gov.nasa.pds.ltdt.label.statement.PrettyObjectStatement;
19 import gov.nasa.pds.ltdt.label.statement.PrettyStatement;
20 import gov.nasa.pds.ltdt.parser.ParserLite;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27 import java.util.List;
28
29 /***
30 * Class to reformat a PDS label so that it will have the
31 * following characteristics:
32 * <ul>
33 * <li>The position of the '=' will be two characters past the longest
34 * element name up to a maximum predefined position. Default is position
35 * 40.</li>
36 * <li>Lines within objects and groups are indented</li>
37 * <li>Every line ends with a \<CR\>\<LF\></li>
38 * <li>Lines will be wrapped at position 78 with subsequent lines of a
39 * wrapped value being indented 2 positions.</li>
40 * </ul>
41 *
42 *
43 * @author mcayanan
44 *
45 */
46 public class LabelReformatter {
47
48 private static int DEFAULT_MAX_EQUALS = 40;
49 private static String NEWLINE = Character.toString((char)0x0d) + Character.toString((char)0x0a);
50
51 public LabelReformatter() {}
52
53 /***
54 * Return a stream representation of a reformatted PDS label, where
55 * the max position of the '=' will be up to a default position of
56 * 40.
57 *
58 * @param label A stream representation of the PDS label.
59 *
60 * @return A stream representation of a reformatted PDS label.
61 * @throws IOException
62 */
63 public ByteArrayOutputStream reformat(InputStream label) throws IOException {
64 return reformat(label, DEFAULT_MAX_EQUALS);
65 }
66
67 /***
68 * Return a stream that contains a reformatted label, where all
69 * equals sign are aligned and all groups and objects are indented.
70 * The '=' will be one character past the longest element name up to
71 * the given maximum predefined position.
72 *
73 * @param label A stream representation of the PDS label.
74 * @param maxEquals The maximum position of the '='.
75 *
76 * @return A stream representation of the PDS label.
77 * @throws IOException
78 */
79 public ByteArrayOutputStream reformat(InputStream label, int maxEquals)
80 throws IOException {
81 short indent = 0;
82 ByteArrayOutputStream output = new ByteArrayOutputStream();
83 List statements = new ArrayList();
84 ParserLite parser = new ParserLite();
85 statements = parser.parse(label);
86
87
88
89 int maxLength = getMaxIdentifierLength(statements, (short) 0) + 2;
90 int maxValue = Math.min(maxLength, maxEquals) + 1;
91
92 for(Iterator i=statements.iterator(); i.hasNext();) {
93 Object object = i.next();
94 try {
95 PrettyStatement s = (PrettyStatement) object;
96 String line = new String(s.toString(indent, maxValue)) + NEWLINE;
97 output.write(line.getBytes());
98 } catch(ClassCastException ce) {
99 String line = new String(object.toString()) + NEWLINE;
100 output.write(line.getBytes());
101 } catch(IllegalArgumentException ae) {
102
103 PrettyCommentStatement cs = (PrettyCommentStatement) object;
104 String line = new String(cs.toString(indent)) + NEWLINE;
105 output.write(line.getBytes());
106 }
107 }
108 return output;
109 }
110
111 /***
112 * Get the longest identifier length out of the given list of statements.
113 *
114 * @param prettyStatements The list of PrettyStatement objects.
115 * @param indent The number of spaces that the statement will be indented.
116 *
117 * @return The value of the longest identifier length, including
118 * the indentation.
119 */
120 public int getMaxIdentifierLength(List prettyStatements, short indent) {
121 int maxValue = 0;
122
123 for(Iterator i=prettyStatements.iterator(); i.hasNext();) {
124 int length = 0;
125 try {
126 PrettyStatement s = (PrettyStatement) i.next();
127 if(s instanceof PrettyAttributeStatement) {
128 PrettyAttributeStatement ps = (PrettyAttributeStatement) s;
129 length = ps.getIdentifier().length() + indent;
130 }
131 else if(s instanceof PrettyObjectStatement) {
132 PrettyObjectStatement o = (PrettyObjectStatement) s;
133 length = getMaxIdentifierLength(o.getStatements(), (short)(indent + 2));
134 }
135 else if(s instanceof PrettyGroupStatement) {
136 PrettyGroupStatement g = (PrettyGroupStatement) s;
137 length = getMaxIdentifierLength(g.getStatements(), (short)(indent + 2));
138 }
139 maxValue = Math.max(length, maxValue);
140 } catch(ClassCastException c) {
141
142 }
143 }
144 return maxValue;
145 }
146 }