001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.service.group;
019:
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.LinkedList;
023: import java.util.List;
024: import java.util.Map;
025:
026: import org.ofbiz.base.util.Debug;
027: import org.ofbiz.base.util.UtilXml;
028: import org.ofbiz.service.GenericServiceException;
029: import org.ofbiz.service.ServiceDispatcher;
030: import org.ofbiz.service.ServiceUtil;
031:
032: import org.w3c.dom.Element;
033:
034: /**
035: * GroupModel.java
036: */
037: public class GroupModel {
038:
039: public static final String module = GroupModel.class.getName();
040:
041: private String groupName, sendMode;
042: private List services;
043: private boolean optional = false;
044: private int lastServiceRan;
045:
046: /**
047: * Constructor using DOM Element
048: * @param group DOM element for the group
049: */
050: public GroupModel(Element group) {
051: this .sendMode = group.getAttribute("send-mode");
052: this .groupName = group.getAttribute("name");
053: this .services = new LinkedList();
054: this .lastServiceRan = -1;
055:
056: if (groupName == null) {
057: throw new IllegalArgumentException(
058: "Group Definition found with no name attribute! : "
059: + group);
060: }
061:
062: List serviceList = UtilXml.childElementList(group, "invoke");
063: if (serviceList != null && serviceList.size() > 0) {
064: Iterator i = serviceList.iterator();
065: while (i.hasNext()) {
066: Element service = (Element) i.next();
067: services.add(new GroupServiceModel(service));
068: }
069: }
070:
071: List oldServiceTags = UtilXml
072: .childElementList(group, "service");
073: if (oldServiceTags != null && oldServiceTags.size() > 0) {
074: Iterator i = oldServiceTags.iterator();
075: while (i.hasNext()) {
076: Element service = (Element) i.next();
077: services.add(new GroupServiceModel(service));
078: }
079: Debug
080: .logWarning(
081: "Service Group Definition : ["
082: + group.getAttribute("name")
083: + "] found with OLD 'service' attribute, change to use 'invoke'",
084: module);
085: }
086:
087: if (Debug.verboseOn())
088: Debug.logVerbose("Created Service Group Model --> " + this ,
089: module);
090: }
091:
092: /**
093: * Basic Constructor
094: * @param groupName Name of the group
095: * @param sendMode Mode used (see DTD)
096: * @param services List of GroupServiceModel objects
097: */
098: public GroupModel(String groupName, String sendMode, List services) {
099: this .lastServiceRan = -1;
100: this .groupName = groupName;
101: this .sendMode = sendMode;
102: this .services = services;
103: }
104:
105: /**
106: * Getter for group name
107: * @return String
108: */
109: public String getGroupName() {
110: return this .groupName;
111: }
112:
113: /**
114: * Getter for send mode
115: * @return String
116: */
117: public String getSendMode() {
118: return this .sendMode;
119: }
120:
121: /**
122: * Returns a list of services in this group
123: * @return List
124: */
125: public List getServices() {
126: return this .services;
127: }
128:
129: /**
130: * Invokes the group of services in order defined
131: * @param dispatcher ServiceDispatcher used for invocation
132: * @param localName Name of the LocalDispatcher (namespace)
133: * @param context Full parameter context (combined for all services)
134: * @return Map Result Map
135: * @throws GenericServiceException
136: */
137: public Map run(ServiceDispatcher dispatcher, String localName,
138: Map context) throws GenericServiceException {
139: if (this .getSendMode().equals("all")) {
140: return runAll(dispatcher, localName, context);
141: } else if (this .getSendMode().equals("round-robin")) {
142: return runIndex(dispatcher, localName, context,
143: (++lastServiceRan % services.size()));
144: } else if (this .getSendMode().equals("random")) {
145: int randomIndex = (int) (Math.random() * (double) (services
146: .size()));
147: return runIndex(dispatcher, localName, context, randomIndex);
148: } else if (this .getSendMode().equals("first-available")) {
149: return runOne(dispatcher, localName, context);
150: } else if (this .getSendMode().equals("none")) {
151: return new HashMap();
152: } else {
153: throw new GenericServiceException(
154: "This mode is not currently supported");
155: }
156: }
157:
158: /**
159: * @see java.lang.Object#toString()
160: */
161: public String toString() {
162: StringBuffer str = new StringBuffer();
163: str.append(getGroupName());
164: str.append("::");
165: str.append(getSendMode());
166: str.append("::");
167: str.append(getServices());
168: return str.toString();
169: }
170:
171: private Map runAll(ServiceDispatcher dispatcher, String localName,
172: Map context) throws GenericServiceException {
173: Map runContext = new HashMap(context);
174: Map result = new HashMap();
175: Iterator i = services.iterator();
176: while (i.hasNext()) {
177: GroupServiceModel model = (GroupServiceModel) i.next();
178: if (Debug.verboseOn())
179: Debug
180: .logVerbose("Using Context: " + runContext,
181: module);
182: Map this Result = model.invoke(dispatcher, localName,
183: runContext);
184: if (Debug.verboseOn())
185: Debug.logVerbose("Result: " + this Result, module);
186:
187: // make sure we didn't fail
188: if (ServiceUtil.isError(this Result)) {
189: Debug.logError("Grouped service [" + model.getName()
190: + "] failed.", module);
191: return this Result;
192: }
193:
194: result.putAll(this Result);
195: if (model.resultToContext()) {
196: runContext.putAll(this Result);
197: Debug.logVerbose("Added result(s) to context.", module);
198: }
199: }
200: return result;
201: }
202:
203: private Map runIndex(ServiceDispatcher dispatcher,
204: String localName, Map context, int index)
205: throws GenericServiceException {
206: GroupServiceModel model = (GroupServiceModel) services
207: .get(index);
208: return model.invoke(dispatcher, localName, context);
209: }
210:
211: private Map runOne(ServiceDispatcher dispatcher, String localName,
212: Map context) throws GenericServiceException {
213: Map result = null;
214: Iterator i = services.iterator();
215: while (i.hasNext() && result != null) {
216: GroupServiceModel model = (GroupServiceModel) i.next();
217: try {
218: result = model.invoke(dispatcher, localName, context);
219: } catch (GenericServiceException e) {
220: Debug
221: .logError("Service: " + model + " failed.",
222: module);
223: }
224: }
225: if (result == null) {
226: throw new GenericServiceException(
227: "All services failed to run; none available.");
228: }
229: return result;
230: }
231: }
|