001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.deployment;
023:
024: import java.util.ArrayList;
025: import java.util.HashSet;
026: import java.util.List;
027: import java.util.Set;
028: import java.util.StringTokenizer;
029:
030: import org.jboss.logging.Logger;
031:
032: /**
033: * SuffixOrderHelper.
034: *
035: * This class wraps the SuffixOrder and EnhandedSuffixes attributes
036: * of MainDeployer.
037: *
038: * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
039: * @version $Revision: 57205 $
040: */
041: public final class SuffixOrderHelper {
042: // Constants -----------------------------------------------------
043:
044: /**
045: * Default EnhancedSuffixes
046: *
047: * Those values are indicative - we just know they'll work with
048: * the compiled order of subdeployers like the aop or ejb3,
049: * but any order can be set using the EnhancedSuffixes
050: * attribute and/or the individual subdeployer's relative order.
051: *
052: * The commented out entries indicate those are dynamically
053: * added by their respective subdeployers when they register.
054: */
055: public static final String[] DEFAULT_ENHANCED_SUFFIXES = {};
056: /*
057: Moved this list to org.jboss.deployment.MainDeployer-xmbean.xml
058: so there are no hardcoded defaults.
059: {
060: //"050:.deployer",
061: //"050:-deployer.xml",
062: //"100:.aop",
063: //"100:-aop.xml",
064: //"150:.sar",
065: //"150:-service.xml",
066: //"200:.beans",
067: "250:.rar",
068: "300:-ds.xml",
069: //"350:.har",
070: "400:.jar", // ejb .jar
071: //"450:.ejb3",
072: //"450:.par",
073: "500:.war", // don't comment out this!
074: "600:.wsr",
075: "650:.ear",
076: //"700:.jar", // plain .jar
077: //"750:.zip",
078: "800:.bsh",
079: "900:.last" // the JARDeployer really handles those?
080: };
081: */
082:
083: /** A default relative order just before 900:.last */
084: public static final int DEFAULT_RELATIVE_ORDER = 850;
085:
086: /** The Logger */
087: public static final Logger log = Logger
088: .getLogger(SuffixOrderHelper.class);
089:
090: // Private Data --------------------------------------------------
091:
092: /** Wrapped DeploymentSorter that stores the value for SuffixOrder attribute */
093: private final DeploymentSorter sorter;
094:
095: /** The actual value of EnhancedSuffixes attribute */
096: private String[] enhancedSuffixes;
097:
098: /** List of sorted EnhancedSuffix instances */
099: private List suffixes;
100:
101: /** Set of static String suffixes that cannot be overriden/removed */
102: private Set staticSuffixes;
103:
104: // Constructor ---------------------------------------------------
105:
106: public SuffixOrderHelper(DeploymentSorter sorter) {
107: this .sorter = sorter;
108: this .suffixes = new ArrayList();
109: this .staticSuffixes = new HashSet();
110: }
111:
112: // Accessors -----------------------------------------------------
113:
114: /**
115: * Getter only for the SuffixOrder as known by the MainDeployer and the Scanners
116: *
117: * The value is updated during init() with suffixes that remain constant.
118: * After that suffixes are added/removed using the corresponding methods.
119: *
120: * @return the SuffixOrder string array
121: */
122: public String[] getSuffixOrder() {
123: return sorter.getSuffixOrder();
124: }
125:
126: /**
127: * Getter for the EnhancedSuffixes attribute
128: *
129: * @return the EnhancedSuffixes string array
130: */
131: public String[] getEnhancedSuffixes() {
132: return enhancedSuffixes;
133: }
134:
135: /**
136: * Setter for the EnhancedSuffixes attribute
137: *
138: * @param enhancedSuffixes the EnhancedSuffixes string array
139: */
140: public void setEnhancedSuffixes(String[] enhancedSuffixes) {
141: this .enhancedSuffixes = enhancedSuffixes;
142: }
143:
144: /**
145: * Initialise the SuffixOrder from EnhancedSuffixes.
146: *
147: * If no enchangedSuffixes is specified, DEFAULT_ENHANCED_SUFFIXES
148: * will be used. Individual entries may contain an additional order
149: * element of the form [order:]suffix, e.g. 100:.sar
150: *
151: * The suffixes specified during init, will remain constant,
152: * i.e. they can't be overriden or removed.
153: */
154: public void initialize() {
155: // if enhancedSuffixes not provided, use the default
156: if (enhancedSuffixes == null) {
157: enhancedSuffixes = DEFAULT_ENHANCED_SUFFIXES;
158: }
159:
160: // reset, just in case we are called more than once
161: suffixes.clear();
162: staticSuffixes.clear();
163:
164: // add all enhanced suffixes; mark them as static, too.
165: for (int i = 0; i < enhancedSuffixes.length; i++) {
166: EnhancedSuffix es = new EnhancedSuffix(enhancedSuffixes[i]);
167: addSuffix(es);
168:
169: // mark all initial entries as static!
170: staticSuffixes.add(es.suffix);
171: }
172:
173: // set the resulting SuffixOrder
174: sorter.setSuffixOrder(produceSuffixOrder());
175: }
176:
177: /**
178: * Add the specified enhanced suffixes in the correct
179: * position(s) and regenerate the SuffixOrder, if needed.
180: *
181: * A suffix that exists already and is marked as static
182: * will be skipped. Otherwise, duplicate entries are allowed.
183: */
184: public void addEnhancedSuffixes(String[] enhancedSuffixes) {
185: if (enhancedSuffixes != null) {
186: // remember the initial size of the list
187: int size = suffixes.size();
188:
189: // add all enhanced suffixes
190: for (int i = 0; i < enhancedSuffixes.length; i++) {
191: EnhancedSuffix es = new EnhancedSuffix(
192: enhancedSuffixes[i]);
193: addSuffix(es);
194: }
195: if (suffixes.size() > size) {
196: // suffixes were added, recreate the resulting SuffixOrder
197: sorter.setSuffixOrder(produceSuffixOrder());
198: }
199: }
200: }
201:
202: /**
203: * Insert the specified suffixes in the correct position
204: * and regenerate the SuffixOrder array, if needed.
205: *
206: * A suffix that exists already and is marked as static
207: * will be skipped. Otherwise, duplicate entries are allowed.
208: */
209: public void addSuffixes(String[] suffixes, int relativeOrder) {
210: if (suffixes != null) {
211: // remember the initial size of the list
212: int size = this .suffixes.size();
213:
214: for (int i = 0; i < suffixes.length; i++) {
215: addSuffix(new EnhancedSuffix(suffixes[i], relativeOrder));
216: }
217:
218: if (this .suffixes.size() > size) {
219: // suffixes were added, recreate the resulting SuffixOrder
220: sorter.setSuffixOrder(produceSuffixOrder());
221: }
222: }
223: }
224:
225: /**
226: * Remove the enhanced suffixes if they are not marked as static
227: * and regenerate the SuffixOrder, if needed.
228: */
229: public void removeEnhancedSuffixes(String[] enhancedSuffixes) {
230: if (enhancedSuffixes != null) {
231: // remember the initial size of the list
232: int size = suffixes.size();
233:
234: for (int i = 0; i < enhancedSuffixes.length; i++) {
235: EnhancedSuffix es = new EnhancedSuffix(
236: enhancedSuffixes[i]);
237:
238: // if this is a static suffix, don't remove
239: if (staticSuffixes.contains(es.suffix)) {
240: continue;
241: } else {
242: // remove if exists
243: suffixes.remove(es);
244: }
245: }
246:
247: if (this .suffixes.size() < size) {
248: // entries removed, recreate the resulting SuffixOrder
249: sorter.setSuffixOrder(produceSuffixOrder());
250: }
251: }
252: }
253:
254: /**
255: * Remove the specified suffixes if they are not marked as static
256: * and regenerate the SuffixOrder, if needed.
257: */
258: public void removeSuffixes(String[] suffixes, int relativeOrder) {
259: if (suffixes != null) {
260: // remember the initial size of the list
261: int size = this .suffixes.size();
262:
263: for (int i = 0; i < suffixes.length; i++) {
264: // if this is a static suffix, don't remove
265: if (staticSuffixes.contains(suffixes[i])) {
266: continue;
267: } else {
268: // remove if exists
269: this .suffixes.remove(new EnhancedSuffix(
270: suffixes[i], relativeOrder));
271: }
272: }
273:
274: if (this .suffixes.size() < size) {
275: // entries removed, recreate the resulting SuffixOrder
276: sorter.setSuffixOrder(produceSuffixOrder());
277: }
278: }
279: }
280:
281: // Private -------------------------------------------------------
282:
283: /**
284: * Produce the SuffixOrder from the sorted suffixes ArrayList
285: */
286: private String[] produceSuffixOrder() {
287: String[] suffixOrder = new String[suffixes.size()];
288:
289: for (int i = 0; i < suffixes.size(); i++) {
290: suffixOrder[i] = ((EnhancedSuffix) suffixes.get(i)).suffix;
291: }
292: return suffixOrder;
293: }
294:
295: /**
296: * Add an EnhancedSuffix at the correct position in the sorted List.
297: *
298: * Sorting is based on EnhancedSuffix.order. A new entry with an equal
299: * order value to an existing entry is placed AFTER the existing entry.
300: *
301: * If EnhancedSuffix.suffix exists in the staticSuffixes Set the entry
302: * is NOT added. Otherwise, they EnhancedSuffix will be added, even
303: * if it is a duplicate of an existing one.
304: *
305: * @param enhancedsuffix the enhanced suffix
306: */
307: private void addSuffix(EnhancedSuffix enhancedSuffix) {
308: // if this is a static suffix, don't add it
309: if (staticSuffixes.contains(enhancedSuffix.suffix)) {
310: log
311: .debug("Static suffix exists; ignoring request for adding enhanced suffix: "
312: + enhancedSuffix);
313: } else {
314: int size = suffixes.size();
315:
316: // if List empty, just add the suffix
317: if (size == 0) {
318: suffixes.add(enhancedSuffix);
319: } else {
320: // insertion sort starting from the last element
321: for (int i = size - 1; i > -1; i--) {
322: EnhancedSuffix entry = (EnhancedSuffix) suffixes
323: .get(i);
324: if (enhancedSuffix.order >= entry.order) {
325: // add the suffix AFTER the entry and stop
326: suffixes.add(i + 1, enhancedSuffix);
327: break;
328: } else if (i == 0) {
329: // reached the beginning so add the suffix right there
330: suffixes.add(0, enhancedSuffix);
331: }
332: }
333: }
334: }
335: }
336:
337: /**
338: * Inner class that encapsulates an enhanceSuffix
339: * consisting of suffix + order
340: */
341: public final static class EnhancedSuffix {
342: /** The suffix, e.g. .sar */
343: public String suffix;
344:
345: /** The order, by convention a 3 digit number, e.g. 100 */
346: public int order;
347:
348: /**
349: * Simple CTOR
350: */
351: public EnhancedSuffix(String suffix, int order) {
352: this .suffix = suffix;
353: this .order = order;
354: }
355:
356: /**
357: * CTOR that parses an enhancedSuffix string of the form: [order:]suffix
358: * If the optional 'order' is missing, use DEFAULT_RELATIVE_ORDER
359: */
360: public EnhancedSuffix(String enhancedSuffix)
361: throws IllegalArgumentException {
362: StringTokenizer tokenizer = new StringTokenizer(
363: enhancedSuffix, ":");
364: int tokens = tokenizer.countTokens();
365:
366: switch (tokens) {
367: case 1:
368: this .order = DEFAULT_RELATIVE_ORDER;
369: this .suffix = enhancedSuffix;
370: break;
371:
372: case 2:
373: this .order = Integer.parseInt(tokenizer.nextToken());
374: this .suffix = tokenizer.nextToken();
375: break;
376:
377: default:
378: throw new IllegalArgumentException(
379: "Cannot parse enhancedSuffix: "
380: + enhancedSuffix);
381: }
382: }
383:
384: /**
385: * Override equals to allow EnhancedSuffix to be searchable
386: * using ArrayList.indexOf()/ArrayList.lastIndexOf()
387: *
388: * Base equality on both suffix and order
389: */
390: public boolean equals(Object other) {
391: if (other == this )
392: return true;
393:
394: if (!(other instanceof EnhancedSuffix))
395: return false;
396:
397: EnhancedSuffix that = (EnhancedSuffix) other;
398:
399: // suffix shouldn't be null
400: return this .suffix.equals(that.suffix)
401: && this .order == that.order;
402: }
403:
404: /**
405: * Use both fields
406: */
407: public int hashCode() {
408: int result = 17;
409: result = 37 * result + suffix.hashCode();
410: result = 37 * result + order;
411: return result;
412: }
413:
414: /**
415: * Pretty print
416: */
417: public String toString() {
418: return order + ":" + suffix;
419: }
420: }
421: }
|