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(String passFileName) {
114 String fileSeparator = FileSystems.getDefault().getSeparator();
115 if (fileSeparator.equals("\\")) {
116
117 fileSeparator += "\\";
118 }
119 passFileName = passFileName.replaceAll(fileSeparator, "/");
120 passFiles.add(passFileName);
121 }
122
123 public String getDeflateHint() {
124 return deflateHint;
125 }
126
127 public int getEffort() {
128 return effort;
129 }
130
131 public String getLogFile() {
132 return logFile;
133 }
134
135 public String getModificationTime() {
136 return modificationTime;
137 }
138
139 private String getOrDefault(final Map<String, String> map, final String type, final String defaultValue) {
140 return map == null ? defaultValue : map.getOrDefault(type, defaultValue);
141 }
142
143 public long getSegmentLimit() {
144 return segmentLimit;
145 }
146
147 public String getUnknownAttributeAction() {
148 return unknownAttributeAction;
149 }
150
151 public Attribute[] getUnknownAttributePrototypes() {
152 if (unknownAttributeTypes == null) {
153 final List<Attribute> prototypes = new ArrayList<>();
154 addOrUpdateAttributeActions(prototypes, classAttributeActions, AttributeDefinitionBands.CONTEXT_CLASS);
155 addOrUpdateAttributeActions(prototypes, methodAttributeActions, AttributeDefinitionBands.CONTEXT_METHOD);
156 addOrUpdateAttributeActions(prototypes, fieldAttributeActions, AttributeDefinitionBands.CONTEXT_FIELD);
157 addOrUpdateAttributeActions(prototypes, codeAttributeActions, AttributeDefinitionBands.CONTEXT_CODE);
158 unknownAttributeTypes = prototypes.toArray(EMPTY_ATTRIBUTE_ARRAY);
159 }
160 return unknownAttributeTypes;
161 }
162
163 public String getUnknownClassAttributeAction(final String type) {
164 return getOrDefault(classAttributeActions, type, unknownAttributeAction);
165 }
166
167 public String getUnknownCodeAttributeAction(final String type) {
168 return getOrDefault(codeAttributeActions, type, unknownAttributeAction);
169 }
170
171 public String getUnknownFieldAttributeAction(final String type) {
172 return getOrDefault(fieldAttributeActions, type, unknownAttributeAction);
173 }
174
175 public String getUnknownMethodAttributeAction(final String type) {
176 return getOrDefault(methodAttributeActions, type, unknownAttributeAction);
177 }
178
179 public boolean isGzip() {
180 return gzip;
181 }
182
183 public boolean isKeepDeflateHint() {
184 return KEEP.equals(deflateHint);
185 }
186
187 public boolean isKeepFileOrder() {
188 return keepFileOrder;
189 }
190
191 public boolean isPassFile(final String passFileName) {
192 for (String pass : passFiles) {
193 if (passFileName.equals(pass)) {
194 return true;
195 }
196 if (!pass.endsWith(".class")) {
197
198 if (!pass.endsWith("/")) {
199
200
201
202 pass += "/";
203 }
204 return passFileName.startsWith(pass);
205 }
206 }
207 return false;
208 }
209
210 public boolean isStripDebug() {
211 return stripDebug;
212 }
213
214 public boolean isVerbose() {
215 return verbose;
216 }
217
218 public void removePassFile(final String passFileName) {
219 passFiles.remove(passFileName);
220 }
221
222 public void setDeflateHint(final String deflateHint) {
223 if (!KEEP.equals(deflateHint) && !"true".equals(deflateHint) && !"false".equals(deflateHint)) {
224 throw new IllegalArgumentException("Bad argument: -H " + deflateHint + " ? deflate hint should be either true, false or keep (default)");
225 }
226 this.deflateHint = deflateHint;
227 }
228
229
230
231
232
233
234 public void setEffort(final int effort) {
235 this.effort = effort;
236 }
237
238 public void setGzip(final boolean gzip) {
239 this.gzip = gzip;
240 }
241
242 public void setKeepFileOrder(final boolean keepFileOrder) {
243 this.keepFileOrder = keepFileOrder;
244 }
245
246 public void setLogFile(final String logFile) {
247 this.logFile = logFile;
248 }
249
250 public void setModificationTime(final String modificationTime) {
251 if (!KEEP.equals(modificationTime) && !"latest".equals(modificationTime)) {
252 throw new IllegalArgumentException("Bad argument: -m " + modificationTime + " ? transmit modtimes should be either latest or keep (default)");
253 }
254 this.modificationTime = modificationTime;
255 }
256
257 public void setQuiet(final boolean quiet) {
258 this.verbose = !quiet;
259 }
260
261
262
263
264
265
266 public void setSegmentLimit(final long segmentLimit) {
267 this.segmentLimit = segmentLimit;
268 }
269
270
271
272
273
274
275
276 public void setStripDebug(final boolean stripDebug) {
277 this.stripDebug = stripDebug;
278 }
279
280
281
282
283
284
285 public void setUnknownAttributeAction(final String unknownAttributeAction) {
286 this.unknownAttributeAction = unknownAttributeAction;
287 if (!PASS.equals(unknownAttributeAction) && !ERROR.equals(unknownAttributeAction) && !STRIP.equals(unknownAttributeAction)) {
288 throw new IllegalArgumentException("Incorrect option for -U, " + unknownAttributeAction);
289 }
290 }
291
292 public void setVerbose(final boolean verbose) {
293 this.verbose = verbose;
294 }
295
296 }