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