1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.harmony.pack200;
20
21 import java.nio.file.FileSystems;
22 import java.util.ArrayList;
23 import java.util.HashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
27
28 import org.objectweb.asm.Attribute;
29
30
31
32
33 public class PackingOptions {
34
35 private static final Attribute[] EMPTY_ATTRIBUTE_ARRAY = {};
36 public static final long SEGMENT_LIMIT = 1_000_000L;
37 public static final String STRIP = "strip";
38 public static final String ERROR = "error";
39 public static final String PASS = "pass";
40 public static final String KEEP = "keep";
41
42
43 private boolean gzip = true;
44 private boolean stripDebug;
45 private boolean keepFileOrder = true;
46 private long segmentLimit = SEGMENT_LIMIT;
47 private int effort = 5;
48 private String deflateHint = KEEP;
49 private String modificationTime = KEEP;
50 private final List<String> passFiles = new ArrayList<>();
51 private String unknownAttributeAction = PASS;
52 private final Map<String, String> classAttributeActions = new HashMap<>();
53 private final Map<String, String> fieldAttributeActions = new HashMap<>();
54 private final Map<String, String> methodAttributeActions = new HashMap<>();
55 private final Map<String, String> codeAttributeActions = new HashMap<>();
56 private boolean verbose;
57 private String logFile;
58
59 private Attribute[] unknownAttributeTypes;
60
61 public void addClassAttributeAction(final String attributeName, final String action) {
62 classAttributeActions.put(attributeName, action);
63 }
64
65 public void addCodeAttributeAction(final String attributeName, final String action) {
66 codeAttributeActions.put(attributeName, action);
67 }
68
69 public void addFieldAttributeAction(final String attributeName, final String action) {
70 fieldAttributeActions.put(attributeName, action);
71 }
72
73 public void addMethodAttributeAction(final String attributeName, final String action) {
74 methodAttributeActions.put(attributeName, action);
75 }
76
77 private void addOrUpdateAttributeActions(final List<Attribute> prototypes, final Map<String, String> attributeActions, final int tag) {
78 if (attributeActions != null && attributeActions.size() > 0) {
79 NewAttribute newAttribute;
80 for (final Entry<String, String> entry : attributeActions.entrySet()) {
81 final String name = entry.getKey();
82 final String action = entry.getValue();
83 boolean prototypeExists = false;
84 for (final Object prototype : prototypes) {
85 newAttribute = (NewAttribute) prototype;
86 if (newAttribute.type.equals(name)) {
87
88 newAttribute.addContext(tag);
89 prototypeExists = true;
90 break;
91 }
92 }
93
94 if (!prototypeExists) {
95 switch (action) {
96 case ERROR:
97 newAttribute = new NewAttribute.ErrorAttribute(name, tag);
98 break;
99 case STRIP:
100 newAttribute = new NewAttribute.StripAttribute(name, tag);
101 break;
102 case PASS:
103 newAttribute = new NewAttribute.PassAttribute(name, tag);
104 break;
105 default:
106 newAttribute = new NewAttribute(name, action, tag);
107 break;
108 }
109 prototypes.add(newAttribute);
110 }
111 }
112 }
113 }
114
115
116
117
118
119
120 public void addPassFile(final String passFileName) {
121 String fileSeparator = FileSystems.getDefault().getSeparator();
122 if (fileSeparator.equals("\\")) {
123
124 fileSeparator += "\\";
125 }
126 passFiles.add(passFileName.replaceAll(fileSeparator, "/"));
127 }
128
129 public String getDeflateHint() {
130 return deflateHint;
131 }
132
133 public int getEffort() {
134 return effort;
135 }
136
137 public String getLogFile() {
138 return logFile;
139 }
140
141 public String getModificationTime() {
142 return modificationTime;
143 }
144
145 private String getOrDefault(final Map<String, String> map, final String type, final String defaultValue) {
146 return map == null ? defaultValue : map.getOrDefault(type, defaultValue);
147 }
148
149 public long getSegmentLimit() {
150 return segmentLimit;
151 }
152
153 public String getUnknownAttributeAction() {
154 return unknownAttributeAction;
155 }
156
157 public Attribute[] getUnknownAttributePrototypes() {
158 if (unknownAttributeTypes == null) {
159 final List<Attribute> prototypes = new ArrayList<>();
160 addOrUpdateAttributeActions(prototypes, classAttributeActions, AttributeDefinitionBands.CONTEXT_CLASS);
161 addOrUpdateAttributeActions(prototypes, methodAttributeActions, AttributeDefinitionBands.CONTEXT_METHOD);
162 addOrUpdateAttributeActions(prototypes, fieldAttributeActions, AttributeDefinitionBands.CONTEXT_FIELD);
163 addOrUpdateAttributeActions(prototypes, codeAttributeActions, AttributeDefinitionBands.CONTEXT_CODE);
164 unknownAttributeTypes = prototypes.toArray(EMPTY_ATTRIBUTE_ARRAY);
165 }
166 return unknownAttributeTypes;
167 }
168
169 public String getUnknownClassAttributeAction(final String type) {
170 return getOrDefault(classAttributeActions, type, unknownAttributeAction);
171 }
172
173 public String getUnknownCodeAttributeAction(final String type) {
174 return getOrDefault(codeAttributeActions, type, unknownAttributeAction);
175 }
176
177 public String getUnknownFieldAttributeAction(final String type) {
178 return getOrDefault(fieldAttributeActions, type, unknownAttributeAction);
179 }
180
181 public String getUnknownMethodAttributeAction(final String type) {
182 return getOrDefault(methodAttributeActions, type, unknownAttributeAction);
183 }
184
185 public boolean isGzip() {
186 return gzip;
187 }
188
189 public boolean isKeepDeflateHint() {
190 return KEEP.equals(deflateHint);
191 }
192
193 public boolean isKeepFileOrder() {
194 return keepFileOrder;
195 }
196
197 public boolean isPassFile(final String passFileName) {
198 for (String pass : passFiles) {
199 if (passFileName.equals(pass)) {
200 return true;
201 }
202 if (!pass.endsWith(".class")) {
203
204 if (!pass.endsWith("/")) {
205
206
207
208 pass += "/";
209 }
210 return passFileName.startsWith(pass);
211 }
212 }
213 return false;
214 }
215
216 public boolean isStripDebug() {
217 return stripDebug;
218 }
219
220 public boolean isVerbose() {
221 return verbose;
222 }
223
224 public void removePassFile(final String passFileName) {
225 passFiles.remove(passFileName);
226 }
227
228 public void setDeflateHint(final String deflateHint) {
229 if (!KEEP.equals(deflateHint) && !"true".equals(deflateHint) && !"false".equals(deflateHint)) {
230 throw new IllegalArgumentException("Bad argument: -H " + deflateHint + " ? deflate hint should be either true, false or keep (default)");
231 }
232 this.deflateHint = deflateHint;
233 }
234
235
236
237
238
239
240 public void setEffort(final int effort) {
241 this.effort = effort;
242 }
243
244 public void setGzip(final boolean gzip) {
245 this.gzip = gzip;
246 }
247
248 public void setKeepFileOrder(final boolean keepFileOrder) {
249 this.keepFileOrder = keepFileOrder;
250 }
251
252 public void setLogFile(final String logFile) {
253 this.logFile = logFile;
254 }
255
256 public void setModificationTime(final String modificationTime) {
257 if (!KEEP.equals(modificationTime) && !"latest".equals(modificationTime)) {
258 throw new IllegalArgumentException("Bad argument: -m " + modificationTime + " ? transmit modtimes should be either latest or keep (default)");
259 }
260 this.modificationTime = modificationTime;
261 }
262
263 public void setQuiet(final boolean quiet) {
264 this.verbose = !quiet;
265 }
266
267
268
269
270
271
272 public void setSegmentLimit(final long segmentLimit) {
273 this.segmentLimit = segmentLimit;
274 }
275
276
277
278
279
280
281
282 public void setStripDebug(final boolean stripDebug) {
283 this.stripDebug = stripDebug;
284 }
285
286
287
288
289
290
291 public void setUnknownAttributeAction(final String unknownAttributeAction) {
292 this.unknownAttributeAction = unknownAttributeAction;
293 if (!PASS.equals(unknownAttributeAction) && !ERROR.equals(unknownAttributeAction) && !STRIP.equals(unknownAttributeAction)) {
294 throw new IllegalArgumentException("Incorrect option for -U, " + unknownAttributeAction);
295 }
296 }
297
298 public void setVerbose(final boolean verbose) {
299 this.verbose = verbose;
300 }
301
302 }