001: /*
002: * Spoon - http://spoon.gforge.inria.fr/
003: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004: *
005: * This software is governed by the CeCILL-C License under French law and
006: * abiding by the rules of distribution of free software. You can use, modify
007: * and/or redistribute the software under the terms of the CeCILL-C license as
008: * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
009: *
010: * This program is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
013: *
014: * The fact that you are presently reading this means that you have had
015: * knowledge of the CeCILL-C license and that you accept its terms.
016: */
017:
018: package spoon.support;
019:
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.LinkedList;
023: import java.util.Queue;
024:
025: import spoon.processing.AbstractProcessor;
026: import spoon.processing.ProcessingManager;
027: import spoon.processing.Processor;
028: import spoon.processing.Severity;
029: import spoon.reflect.Factory;
030: import spoon.reflect.declaration.CtElement;
031: import spoon.support.util.Timer;
032: import spoon.support.visitor.ProcessingVisitor;
033:
034: /**
035: * This processing manager implements a blocking processing policy that consists
036: * of applying the processors in a FIFO order until no processors remain to be
037: * applied.
038: */
039: public class QueueProcessingManager implements ProcessingManager {
040: Processor<?> current;
041:
042: Factory factory;
043:
044: Queue<Processor<?>> processors;
045:
046: ProcessingVisitor visitor;
047:
048: /**
049: * Creates a new processing manager that maintains a queue of processors to
050: * be applied to a given factory.
051: *
052: * @param factory
053: * the factory on which the processing applies (contains the
054: * meta-model)
055: */
056: public QueueProcessingManager(Factory factory) {
057: super ();
058: setFactory(factory);
059: }
060:
061: public void addProcessor(Class<? extends Processor<?>> type) {
062: try {
063: Processor<?> p = type.newInstance();
064: addProcessor(p);
065: } catch (Exception e) {
066: factory
067: .getEnvironment()
068: .report(
069: null,
070: Severity.ERROR,
071: "Unable to instantiate processor \""
072: + type.getName()
073: + "\" - Your processor should have a constructor with no arguments");
074: }
075: }
076:
077: public boolean addProcessor(Processor<?> p) {
078: p.setFactory(getFactory());
079: return getProcessors().add(p);
080: }
081:
082: @SuppressWarnings("unchecked")
083: public void addProcessor(String qualifiedName) {
084: try {
085: addProcessor((Class<? extends Processor<?>>) Class
086: .forName(qualifiedName));
087: } catch (ClassNotFoundException e) {
088: factory.getEnvironment().report(
089: null,
090: Severity.ERROR,
091: "Unable to load processor \"" + qualifiedName
092: + "\" - Check your classpath");
093: }
094: }
095:
096: public Processor<?> getCurrentProcessor() {
097: return current;
098: }
099:
100: public Factory getFactory() {
101: return factory;
102: }
103:
104: public Queue<Processor<?>> getProcessors() {
105: if (processors == null) {
106: processors = new LinkedList<Processor<?>>();
107: }
108: return processors;
109: }
110:
111: @SuppressWarnings("unchecked")
112: protected ProcessingVisitor getVisitor() {
113: if (visitor == null)
114: visitor = new ProcessingVisitor(getFactory());
115: return visitor;
116: }
117:
118: public boolean isToBeApplied(Class<? extends Processor<?>> type) {
119: for (Processor<?> p : getProcessors()) {
120: if (p.getClass() == type) {
121: return true;
122: }
123: }
124: return false;
125: }
126:
127: public void process() {
128: Timer.start("process");
129: process(getFactory().Package().getAllRoots());
130: Timer.stop("process");
131: }
132:
133: public void process(Collection<? extends CtElement> elements) {
134: Processor<?> p;
135: while ((p = getProcessors().poll()) != null) {
136: if (getFactory().getEnvironment().isVerbose()) {
137: getFactory().getEnvironment().reportProgressMessage(
138: p.getClass().getName());
139: }
140: current = p;
141: p.initProperties(AbstractProcessor.loadProperties(p));
142: p.init();
143: p.process();
144: for (CtElement e : new ArrayList<CtElement>(elements))
145: process(e, p);
146: p.processingDone();
147: }
148: }
149:
150: public void process(CtElement element) {
151: Processor<?> p;
152: while ((p = getProcessors().poll()) != null) {
153: current = p;
154: p.init();
155: p.process();
156: process(element, p);
157: p.processingDone();
158: }
159: }
160:
161: @SuppressWarnings("unchecked")
162: protected void process(CtElement element, Processor<?> processor) {
163: getVisitor().setProcessor(processor);
164: getVisitor().scan(element);
165: }
166:
167: public void setFactory(Factory factory) {
168: this.factory = factory;
169: factory.getEnvironment().setManager(this);
170: }
171:
172: }
|