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