001: // Copyright 2004, 2005 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.hivemind.lib.pipeline;
016:
017: import java.util.List;
018:
019: import org.apache.hivemind.ErrorLog;
020: import org.apache.hivemind.Location;
021: import org.apache.hivemind.impl.BaseLocatable;
022: import org.apache.hivemind.lib.DefaultImplementationBuilder;
023: import org.apache.hivemind.order.Orderer;
024: import org.apache.hivemind.service.ClassFactory;
025:
026: /**
027: * Used by the {@link org.apache.hivemind.lib.pipeline.PipelineFactory} to assemble the pipeline.
028: *
029: * @author Howard Lewis Ship
030: */
031: public class PipelineAssembler extends BaseLocatable {
032: /** @since 1.1 */
033: private ErrorLog _errorLog;
034:
035: private String _serviceId;
036:
037: private Class _serviceInterface;
038:
039: private Class _filterInterface;
040:
041: private ClassFactory _classFactory;
042:
043: private DefaultImplementationBuilder _defaultBuilder;
044:
045: private Orderer _orderer;
046:
047: private Object _terminator;
048:
049: private Location _terminatorLocation;
050:
051: /**
052: * @param errorLog
053: * used for reporting recoverable errors
054: * @param serviceInterface
055: * the main interface
056: * @param filterInterface
057: * the interface for filters
058: * @param classFactory
059: * for creating new classes
060: * @param defaultBuilder
061: * used to provide a placeholder terminator if no real terminator is supplied
062: * @param servceId
063: * of the service being assembled
064: */
065: public PipelineAssembler(ErrorLog errorLog, String serviceId,
066: Class serviceInterface, Class filterInterface,
067: ClassFactory classFactory,
068: DefaultImplementationBuilder defaultBuilder) {
069: _errorLog = errorLog;
070: _serviceId = serviceId;
071: _serviceInterface = serviceInterface;
072: _filterInterface = filterInterface;
073: _classFactory = classFactory;
074: _defaultBuilder = defaultBuilder;
075:
076: _orderer = new Orderer(_errorLog, "filter");
077:
078: }
079:
080: public void addFilter(String name, String prereqs, String postreqs,
081: Object filter, Location location) {
082: if (!checkInterface(_filterInterface, filter, location))
083: return;
084:
085: FilterHolder holder = new FilterHolder(filter, location);
086:
087: _orderer.add(holder, name, prereqs, postreqs);
088: }
089:
090: public void setTerminator(Object terminator,
091: Location terminatorLocation) {
092: if (_terminator != null) {
093: _errorLog.error(PipelineMessages.duplicateTerminator(
094: terminator, _serviceId, _terminator,
095: _terminatorLocation), terminatorLocation, null);
096: return;
097: }
098:
099: if (!checkInterface(_serviceInterface, terminator,
100: terminatorLocation))
101: return;
102:
103: _terminator = terminator;
104: _terminatorLocation = terminatorLocation;
105: }
106:
107: // For testing
108:
109: Object getTerminator() {
110: return _terminator;
111: }
112:
113: private boolean checkInterface(Class interfaceType,
114: Object instance, Location location) {
115: if (interfaceType.isAssignableFrom(instance.getClass()))
116: return true;
117:
118: _errorLog.error(PipelineMessages.incorrectInterface(instance,
119: interfaceType, _serviceId), location, null);
120:
121: return false;
122: }
123:
124: /**
125: * Returns an object that implements the service interface, and integrates any filters for the
126: * pipeline with the
127: */
128: public Object createPipeline() {
129: List filterHolders = _orderer.getOrderedObjects();
130: int count = filterHolders.size();
131:
132: BridgeBuilder bb = (count == 0) ? null : new BridgeBuilder(
133: _errorLog, _serviceId, _serviceInterface,
134: _filterInterface, _classFactory);
135:
136: Object next = _terminator != null ? _terminator
137: : _defaultBuilder
138: .buildDefaultImplementation(_serviceInterface);
139:
140: // Like service interceptors, we work deepest (last) to shallowest (first).
141:
142: for (int i = count - 1; i >= 0; i--) {
143: FilterHolder h = (FilterHolder) filterHolders.get(i);
144: Object filter = h.getFilter();
145:
146: next = bb.instantiateBridge(next, filter);
147: }
148:
149: return next;
150: }
151: }
|