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.apache.james.mailrepository.filepair;
019:
020: import java.net.MalformedURLException;
021: import java.net.URL;
022: import java.util.HashMap;
023: import org.apache.avalon.cornerstone.services.store.Repository;
024: import org.apache.avalon.cornerstone.services.store.Store;
025: import org.apache.avalon.framework.component.Composable;
026: import org.apache.avalon.framework.service.Serviceable;
027: import org.apache.avalon.framework.service.ServiceManager;
028: import org.apache.avalon.framework.service.ServiceException;
029: import org.apache.avalon.framework.configuration.Configurable;
030: import org.apache.avalon.framework.configuration.Configuration;
031: import org.apache.avalon.framework.configuration.ConfigurationException;
032: import org.apache.avalon.framework.container.ContainerUtil;
033: import org.apache.avalon.framework.context.Context;
034: import org.apache.avalon.framework.context.Contextualizable;
035: import org.apache.avalon.framework.logger.AbstractLogEnabled;
036:
037: /**
038: * @phoenix:block
039: * @phoenix:service name="org.apache.avalon.cornerstone.services.store.Store"
040: *
041: */
042: public class RepositoryManager extends AbstractLogEnabled implements
043: Store, Contextualizable, Serviceable, Configurable {
044: private static final String REPOSITORY_NAME = "Repository";
045: private static long id = 0;
046:
047: protected HashMap m_repositories = new HashMap();
048: protected HashMap m_models = new HashMap();
049: protected HashMap m_classes = new HashMap();
050: protected ServiceManager m_componentManager;
051: protected Context m_context;
052:
053: public void contextualize(final Context context) {
054: m_context = context;
055: }
056:
057: public void service(final ServiceManager componentManager)
058: throws ServiceException {
059: m_componentManager = componentManager;
060: }
061:
062: public void configure(final Configuration configuration)
063: throws ConfigurationException {
064: final Configuration[] registeredClasses = configuration
065: .getChild("repositories").getChildren("repository");
066:
067: for (int i = 0; i < registeredClasses.length; i++) {
068: registerRepository(registeredClasses[i]);
069: }
070: }
071:
072: public void registerRepository(final Configuration repConf)
073: throws ConfigurationException {
074: final String className = repConf.getAttribute("class");
075: getLogger().info("Registering Repository " + className);
076:
077: final Configuration[] protocols = repConf.getChild("protocols")
078: .getChildren("protocol");
079: final Configuration[] types = repConf.getChild("types")
080: .getChildren("type");
081: final Configuration[] modelIterator = repConf
082: .getChild("models").getChildren("model");
083:
084: for (int i = 0; i < protocols.length; i++) {
085: final String protocol = protocols[i].getValue();
086:
087: for (int j = 0; j < types.length; j++) {
088: final String type = types[j].getValue();
089:
090: for (int k = 0; k < modelIterator.length; k++) {
091: final String model = modelIterator[k].getValue();
092: m_classes.put(protocol + type + model, className);
093: getLogger().info(
094: " for " + protocol + "," + type + ","
095: + model);
096: }
097: }
098: }
099: }
100:
101: public void release(final Object component) {
102: }
103:
104: public boolean isSelectable(final Object hint) {
105: if (hint instanceof Configuration)
106: return true;
107: else
108: return false;
109: }
110:
111: public Object select(final Object hint) throws ServiceException {
112: Configuration repConf = null;
113: try {
114: repConf = (Configuration) hint;
115: } catch (final ClassCastException cce) {
116: throw new ServiceException("",
117: "Hint is of the wrong type. "
118: + "Must be a Configuration", cce);
119: }
120:
121: URL destination = null;
122: try {
123: destination = new URL(repConf
124: .getAttribute("destinationURL"));
125: } catch (final ConfigurationException ce) {
126: throw new ServiceException("",
127: "Malformed configuration has no "
128: + "destinationURL attribute", ce);
129: } catch (final MalformedURLException mue) {
130: throw new ServiceException("", "destination is malformed. "
131: + "Must be a valid URL", mue);
132: }
133:
134: try {
135: final String type = repConf.getAttribute("type");
136: final String repID = destination + type;
137: Repository reply = (Repository) m_repositories.get(repID);
138: final String model = (String) repConf.getAttribute("model");
139:
140: if (null != reply) {
141: if (m_models.get(repID).equals(model)) {
142: return reply;
143: } else {
144: final String message = "There is already another repository with the "
145: + "same destination and type but with different model";
146: throw new ServiceException("", message);
147: }
148: } else {
149: final String protocol = destination.getProtocol();
150: final String repClass = (String) m_classes.get(protocol
151: + type + model);
152:
153: getLogger().debug(
154: "Need instance of " + repClass + " to handle: "
155: + protocol + type + model);
156:
157: try {
158: reply = (Repository) Class.forName(repClass)
159: .newInstance();
160: setupLogger(reply, "repository");
161:
162: ContainerUtil.contextualize(reply, m_context);
163: ContainerUtil.service(reply, m_componentManager);
164:
165: if (reply instanceof Composable) {
166: final String error = "no implementation in place to support Composable";
167: getLogger().error(error);
168: throw new IllegalArgumentException(error);
169: }
170:
171: ContainerUtil.configure(reply, repConf);
172: ContainerUtil.initialize(reply);
173:
174: m_repositories.put(repID, reply);
175: m_models.put(repID, model);
176: getLogger().info(
177: "New instance of " + repClass
178: + " created for " + destination);
179: return reply;
180: } catch (final Exception e) {
181: final String message = "Cannot find or init repository: "
182: + e.getMessage();
183: getLogger().warn(message, e);
184:
185: throw new ServiceException("", message, e);
186: }
187: }
188: } catch (final ConfigurationException ce) {
189: throw new ServiceException("", "Malformed configuration",
190: ce);
191: }
192: }
193:
194: public static final String getName() {
195: return REPOSITORY_NAME;
196: }
197: }
|