001package org.apache.fulcrum.security.torque.peer;
002/*
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 */
020import java.util.Map;
021import java.util.concurrent.ConcurrentHashMap;
022
023import org.apache.avalon.framework.activity.Disposable;
024import org.apache.fulcrum.security.spi.AbstractManager;
025import org.apache.fulcrum.security.util.DataBackendException;
026
027/**
028 * Use this class, if you want to replace the default Torque Peer classes with your own. 
029 *  
030 * To use it, the PeerImpl classes (usually generated) must implement 
031 * at least the {@linkplain Peer} marker interface or some extended interface.
032 * 
033 * @see PeerManager
034 * 
035 * @author <a href="mailto:gk@apache.org">Georg Kallidis</a>
036 * @version $Id$
037 * 
038 */
039public class PeerManagerDefaultImpl extends AbstractManager
040    implements PeerManager, Disposable
041{
042      
043         /** Serial version */
044        private static final long serialVersionUID = -3891813089694207441L;
045        private Map<String,Peer> peers = new ConcurrentHashMap<String,Peer>(4,0.75f,4);
046
047    /* (non-Javadoc)
048     * @see org.apache.fulcrum.security.torque.peer.PeerManager#getPeerInstance(java.lang.String)
049     */
050    @Override
051    public <P extends Peer> P getPeerInstance(String peerClassName) throws DataBackendException
052    {
053        return getPeerInstance( peerClassName, Peer.class, null);
054    }
055
056    /* (non-Javadoc)
057     * @see org.apache.fulcrum.security.torque.peer.PeerManager#getPeerInstance(java.lang.String, java.lang.Class, java.lang.String)
058     */
059    @SuppressWarnings( "unchecked" )
060    @Override
061    public <P extends Peer> P getPeerInstance( String peerClassName, Class<? extends Peer> peerInterface , String className) throws DataBackendException
062    {
063        if (peers.containsKey(peerClassName )) {
064            getLogger().debug( " get cached PeerInstance():" +  peers.get( peerClassName ));
065            return (P) peers.get( peerClassName );
066        }
067        try
068        {
069            P peer = (P) Class.forName(peerClassName).getConstructor().newInstance();
070            getLogger().debug( " getPeerInstance():" +  peer);
071            peers.put( peerClassName, peer );
072            return peer;
073        }
074        catch (ClassCastException e) {
075            throw new DataBackendException( e.getMessage()+ ".\nThe peer class " + peerClassName + " should implement "+ peerInterface + "\n of generic type <"+className +">.",e );
076        } 
077        catch (Throwable e)
078        {
079            throw new DataBackendException("Problem creating instance of class " + peerClassName, e);
080        }             
081    }
082
083
084}