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: */
019:
020: package org.apache.synapse.config.xml;
021:
022: import org.apache.synapse.Mediator;
023: import org.apache.synapse.mediators.builtin.CacheMediator;
024: import org.apache.axiom.om.OMElement;
025: import org.apache.axiom.om.OMAttribute;
026: import org.wso2.caching.CachingConstants;
027: import org.wso2.caching.digest.DigestGenerator;
028:
029: import javax.xml.namespace.QName;
030: import java.util.Iterator;
031:
032: /**
033: * Creates an instance of a Cache mediator using XML configuration specified
034: *
035: * <pre>
036: * <cache id="string" [hashGenerator="class"] [timeout="seconds"]
037: * [scope=(per-host | per-mediator)] collector=(true | false) [maxMessageSize="in-bytes"]>
038: * <onCacheHit [sequence="key"]>
039: * (mediator)+
040: * </onCacheHit>?
041: * <implementation type=(memory | disk) maxSize="int"/>
042: * </cache>
043: * </pre>
044: */
045: public class CacheMediatorFactory extends AbstractMediatorFactory {
046:
047: private static final QName CACHE_Q = new QName(
048: XMLConfigConstants.SYNAPSE_NAMESPACE, "cache");
049: private static final QName ATT_ID = new QName("id");
050: private static final QName ATT_COLLECTOR = new QName("collector");
051: private static final QName ATT_HASH_GENERATOR = new QName(
052: "hashGenerator");
053: private static final QName ATT_MAX_MSG_SIZE = new QName(
054: "maxMessageSize");
055: private static final QName ATT_TIMEOUT = new QName("timeout");
056: private static final QName ATT_SCOPE = new QName("scope");
057: private static final QName ATT_SEQUENCE = new QName("sequence");
058: private static final QName ATT_TYPE = new QName("type");
059: private static final QName ATT_SIZE = new QName("maxSize");
060: private static final QName ON_CACHE_HIT_Q = new QName(
061: XMLConfigConstants.SYNAPSE_NAMESPACE, "onCacheHit");
062: private static final QName IMPLEMENTATION_Q = new QName(
063: XMLConfigConstants.SYNAPSE_NAMESPACE, "implementation");
064: private static final long DEFAULT_TIMEOUT = 5000L;
065: private static final int DEFAULT_DISK_CACHE_SIZE = 200;
066:
067: public Mediator createMediator(OMElement elem) {
068:
069: if (!CACHE_Q.equals(elem.getQName())) {
070: handleException("Unable to create the cache mediator. "
071: + "Unexpected element as the cache mediator configuration");
072: }
073:
074: CacheMediator cache = new CacheMediator();
075:
076: OMAttribute idAttr = elem.getAttribute(ATT_ID);
077: if (idAttr != null && idAttr.getAttributeValue() != null) {
078: cache.setId(idAttr.getAttributeValue());
079: }
080:
081: OMAttribute scopeAttr = elem.getAttribute(ATT_SCOPE);
082: if (scopeAttr != null
083: && scopeAttr.getAttributeValue() != null
084: && isValidScope(scopeAttr.getAttributeValue(), cache
085: .getId())) {
086: cache.setScope(scopeAttr.getAttributeValue());
087: } else {
088: cache.setScope(CachingConstants.SCOPE_PER_HOST);
089: }
090:
091: OMAttribute collectorAttr = elem.getAttribute(ATT_COLLECTOR);
092: if (collectorAttr != null
093: && collectorAttr.getAttributeValue() != null
094: && "true".equals(collectorAttr.getAttributeValue())) {
095:
096: cache.setCollector(true);
097: } else {
098:
099: cache.setCollector(false);
100:
101: OMAttribute hashGeneratorAttr = elem
102: .getAttribute(ATT_HASH_GENERATOR);
103: if (hashGeneratorAttr != null
104: && hashGeneratorAttr.getAttributeValue() != null) {
105: try {
106: Class generator = Class.forName(hashGeneratorAttr
107: .getAttributeValue());
108: Object o = generator.newInstance();
109: if (o instanceof DigestGenerator) {
110: cache.setDigestGenerator((DigestGenerator) o);
111: } else {
112: handleException("Specified class for the hashGenerator is not a "
113: + "DigestGenerator. It *must* implement "
114: + "org.wso2.caching.digest.DigestGenerator interface");
115: }
116: } catch (ClassNotFoundException e) {
117: handleException(
118: "Unable to load the hash generator class",
119: e);
120: } catch (IllegalAccessException e) {
121: handleException(
122: "Unable to access the hash generator class",
123: e);
124: } catch (InstantiationException e) {
125: handleException(
126: "Unable to instantiate the hash generator class",
127: e);
128: }
129: }
130:
131: OMAttribute timeoutAttr = elem.getAttribute(ATT_TIMEOUT);
132: if (timeoutAttr != null
133: && timeoutAttr.getAttributeValue() != null) {
134: cache.setTimeout(Long.parseLong(timeoutAttr
135: .getAttributeValue()));
136: } else {
137: cache.setTimeout(DEFAULT_TIMEOUT);
138: }
139:
140: OMAttribute maxMessageSizeAttr = elem
141: .getAttribute(ATT_MAX_MSG_SIZE);
142: if (maxMessageSizeAttr != null
143: && maxMessageSizeAttr.getAttributeValue() != null) {
144: cache.setMaxMessageSize(Integer
145: .parseInt(maxMessageSizeAttr
146: .getAttributeValue()));
147: }
148:
149: OMElement onCacheHitElem = elem
150: .getFirstChildWithName(ON_CACHE_HIT_Q);
151: if (onCacheHitElem != null) {
152: OMAttribute sequenceAttr = onCacheHitElem
153: .getAttribute(ATT_SEQUENCE);
154: if (sequenceAttr != null
155: && sequenceAttr.getAttributeValue() != null) {
156: cache.setOnCacheHitRef(sequenceAttr
157: .getAttributeValue());
158: } else if (onCacheHitElem.getFirstElement() != null) {
159: cache
160: .setOnCacheHitSequence(new SequenceMediatorFactory()
161: .createAnonymousSequence(onCacheHitElem));
162: }
163: }
164:
165: for (Iterator itr = elem
166: .getChildrenWithName(IMPLEMENTATION_Q); itr
167: .hasNext();) {
168: OMElement implElem = (OMElement) itr.next();
169: OMAttribute typeAttr = implElem.getAttribute(ATT_TYPE);
170: OMAttribute sizeAttr = implElem.getAttribute(ATT_SIZE);
171: if (typeAttr != null
172: && typeAttr.getAttributeValue() != null) {
173: String type = typeAttr.getAttributeValue();
174: if (CachingConstants.TYPE_MEMORY.equals(type)
175: && sizeAttr != null
176: && sizeAttr.getAttributeValue() != null) {
177: cache
178: .setInMemoryCacheSize(Integer
179: .parseInt(sizeAttr
180: .getAttributeValue()));
181: } else if (CachingConstants.TYPE_DISK.equals(type)) {
182: log
183: .warn("Disk based and hirearchycal caching is not implemented yet");
184: if (sizeAttr != null
185: && sizeAttr.getAttributeValue() != null) {
186: cache.setDiskCacheSize(Integer
187: .parseInt(sizeAttr
188: .getAttributeValue()));
189: } else {
190: cache
191: .setDiskCacheSize(DEFAULT_DISK_CACHE_SIZE);
192: }
193: } else {
194: handleException("unknown implementation type for the Cache mediator");
195: }
196: }
197: }
198: }
199:
200: return cache;
201: }
202:
203: private boolean isValidScope(String scope, String id) {
204: if (CachingConstants.SCOPE_PER_HOST.equals(scope)) {
205: return true;
206: } else if (CachingConstants.SCOPE_PER_MEDIATOR.equals(scope)) {
207: if (id != null) {
208: return true;
209: } else {
210: handleException("Id is required for a cache wirth scope : "
211: + scope);
212: return false;
213: }
214: } else if (CachingConstants.SCOPE_DISTRIBUTED.equals(scope)) {
215: handleException("Scope distributed is not supported yet by the Cache mediator");
216: return false;
217: } else {
218: handleException("Unknown scope " + scope
219: + " for the Cache mediator");
220: return false;
221: }
222: }
223:
224: public QName getTagQName() {
225: return CACHE_Q;
226: }
227: }
|