1 /***************************************************************** 2 * Licensed to the Apache Software Foundation (ASF) under one * 3 * or more contributor license agreements. See the NOTICE file * 4 * distributed with this work for additional information * 5 * regarding copyright ownership. The ASF licenses this file * 6 * to you under the Apache License, Version 2.0 (the * 7 * "License"); you may not use this file except in compliance * 8 * with the License. You may obtain a copy of the License at * 9 * * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, * 13 * software distributed under the License is distributed on an * 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15 * KIND, either express or implied. See the License for the * 16 * specific language governing permissions and limitations * 17 * under the License. * 18 ****************************************************************/ 19 20 package org.apache.james.mailrepository.filepair; 21 22 import java.net.MalformedURLException; 23 import java.net.URL; 24 import java.util.HashMap; 25 import org.apache.avalon.cornerstone.services.store.Repository; 26 import org.apache.avalon.cornerstone.services.store.Store; 27 import org.apache.avalon.framework.component.Composable; 28 import org.apache.avalon.framework.service.Serviceable; 29 import org.apache.avalon.framework.service.ServiceManager; 30 import org.apache.avalon.framework.service.ServiceException; 31 import org.apache.avalon.framework.configuration.Configurable; 32 import org.apache.avalon.framework.configuration.Configuration; 33 import org.apache.avalon.framework.configuration.ConfigurationException; 34 import org.apache.avalon.framework.container.ContainerUtil; 35 import org.apache.avalon.framework.context.Context; 36 import org.apache.avalon.framework.context.Contextualizable; 37 import org.apache.avalon.framework.logger.AbstractLogEnabled; 38 39 /*** 40 * @phoenix:block 41 * @phoenix:service name="org.apache.avalon.cornerstone.services.store.Store" 42 * 43 */ 44 public class RepositoryManager 45 extends AbstractLogEnabled 46 implements Store, Contextualizable, Serviceable, Configurable 47 { 48 private static final String REPOSITORY_NAME = "Repository"; 49 private static long id = 0; 50 51 protected HashMap m_repositories = new HashMap(); 52 protected HashMap m_models = new HashMap(); 53 protected HashMap m_classes = new HashMap(); 54 protected ServiceManager m_componentManager; 55 protected Context m_context; 56 57 public void contextualize( final Context context ) 58 { 59 m_context = context; 60 } 61 62 public void service( final ServiceManager componentManager ) 63 throws ServiceException 64 { 65 m_componentManager = componentManager; 66 } 67 68 public void configure( final Configuration configuration ) 69 throws ConfigurationException 70 { 71 final Configuration[] registeredClasses = 72 configuration.getChild( "repositories" ).getChildren( "repository" ); 73 74 for( int i = 0; i < registeredClasses.length; i++ ) 75 { 76 registerRepository( registeredClasses[ i ] ); 77 } 78 } 79 80 public void registerRepository( final Configuration repConf ) 81 throws ConfigurationException 82 { 83 final String className = repConf.getAttribute( "class" ); 84 getLogger().info( "Registering Repository " + className ); 85 86 final Configuration[] protocols = 87 repConf.getChild( "protocols" ).getChildren( "protocol" ); 88 final Configuration[] types = repConf.getChild( "types" ).getChildren( "type" ); 89 final Configuration[] modelIterator = 90 repConf.getChild( "models" ).getChildren( "model" ); 91 92 for( int i = 0; i < protocols.length; i++ ) 93 { 94 final String protocol = protocols[ i ].getValue(); 95 96 for( int j = 0; j < types.length; j++ ) 97 { 98 final String type = types[ j ].getValue(); 99 100 for( int k = 0; k < modelIterator.length; k++ ) 101 { 102 final String model = modelIterator[ k ].getValue(); 103 m_classes.put( protocol + type + model, className ); 104 getLogger().info( " for " + protocol + "," + type + "," + model ); 105 } 106 } 107 } 108 } 109 110 public void release( final Object component ) 111 { 112 } 113 114 public boolean isSelectable( final Object hint ) 115 { 116 if( hint instanceof Configuration ) 117 return true; 118 else 119 return false; 120 } 121 122 public Object select( final Object hint ) 123 throws ServiceException 124 { 125 Configuration repConf = null; 126 try 127 { 128 repConf = (Configuration)hint; 129 } 130 catch( final ClassCastException cce ) 131 { 132 throw new ServiceException("", "Hint is of the wrong type. " + 133 "Must be a Configuration", cce ); 134 } 135 136 URL destination = null; 137 try 138 { 139 destination = new URL( repConf.getAttribute( "destinationURL" ) ); 140 } 141 catch( final ConfigurationException ce ) 142 { 143 throw new ServiceException("","Malformed configuration has no " + 144 "destinationURL attribute", ce ); 145 } 146 catch( final MalformedURLException mue ) 147 { 148 throw new ServiceException("", "destination is malformed. " + 149 "Must be a valid URL", mue ); 150 } 151 152 try 153 { 154 final String type = repConf.getAttribute( "type" ); 155 final String repID = destination + type; 156 Repository reply = (Repository)m_repositories.get( repID ); 157 final String model = (String)repConf.getAttribute( "model" ); 158 159 if( null != reply ) 160 { 161 if( m_models.get( repID ).equals( model ) ) 162 { 163 return reply; 164 } 165 else 166 { 167 final String message = "There is already another repository with the " + 168 "same destination and type but with different model"; 169 throw new ServiceException("", message ); 170 } 171 } 172 else 173 { 174 final String protocol = destination.getProtocol(); 175 final String repClass = (String)m_classes.get( protocol + type + model ); 176 177 getLogger().debug( "Need instance of " + repClass + " to handle: " + 178 protocol + type + model ); 179 180 try 181 { 182 reply = (Repository)Class.forName( repClass ).newInstance(); 183 setupLogger( reply, "repository" ); 184 185 ContainerUtil.contextualize(reply,m_context); 186 ContainerUtil.service(reply,m_componentManager); 187 188 if (reply instanceof Composable) { 189 final String error = "no implementation in place to support Composable"; 190 getLogger().error( error ); 191 throw new IllegalArgumentException( error ); 192 } 193 194 ContainerUtil.configure(reply,repConf); 195 ContainerUtil.initialize(reply); 196 197 m_repositories.put( repID, reply ); 198 m_models.put( repID, model ); 199 getLogger().info( "New instance of " + repClass + " created for " + 200 destination ); 201 return reply; 202 } 203 catch( final Exception e ) 204 { 205 final String message = "Cannot find or init repository: " + e.getMessage(); 206 getLogger().warn( message, e ); 207 208 throw new ServiceException("", message, e ); 209 } 210 } 211 } 212 catch( final ConfigurationException ce ) 213 { 214 throw new ServiceException("", "Malformed configuration", ce ); 215 } 216 } 217 218 public static final String getName() 219 { 220 return REPOSITORY_NAME; 221 } 222 }