    001    package org.apache.turbine.om;
    002
    003
    004    /*
    005     * Licensed to the Apache Software Foundation (ASF) under one
    006     * or more contributor license agreements.  See the NOTICE file
    007     * distributed with this work for additional information
    008     * regarding copyright ownership.  The ASF licenses this file
    009     * to you under the Apache License, Version 2.0 (the
    010     * "License"); you may not use this file except in compliance
    011     * with the License.  You may obtain a copy of the License at
    012     *
    013     *   http://www.apache.org/licenses/LICENSE-2.0
    014     *
    015     * Unless required by applicable law or agreed to in writing,
    016     * software distributed under the License is distributed on an
    017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018     * KIND, either express or implied.  See the License for the
    019     * specific language governing permissions and limitations
    020     * under the License.
    021     */
    022
    023
    024    import java.util.HashMap;
    025    import java.util.Map;
    026
    027    import org.apache.fulcrum.pool.Recyclable;
    028    import org.apache.turbine.services.pull.ApplicationTool;
    029
    030    /**
    031     * A Pull tool to make om objects available to a template
    032     *
    033     * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
    034     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    035     * @version $Id: OMTool.java 1078552 2011-03-06 19:58:46Z tv $
    036     */
    037    public class OMTool implements ApplicationTool, Recyclable
    038    {
    039        // private RunData data;
    040        protected HashMap<String, Object> omMap;
    041
    042        // note the following could be a static attribute to reduce memory
    043        // footprint. Might require a service to front load the
    044        // PullHelpers to avoid MT issues. A multiple write is not so bad
    045        // though
    046
    047        /** The cache of PullHelpers. **/
    048        private static Map<String, OMTool.PullHelper> pullMap = new HashMap<String, OMTool.PullHelper>();
    049
    050        /**
    051         *  The Factory responsible for retrieving the
    052         *  objects from storage
    053         */
    054        protected RetrieverFactory omFactory;
    055
    056        public OMTool()throws Exception
    057        {
    058            omMap = new HashMap<String, Object>();
    059            //String className = Turbine.getConfiguration()
    060            //       .getString("tool.om.factory");
    061            //        RetrieverFactory omFactory =
    062            //            (RetrieverFactory)Class.forName(className).newInstance();
    063        }
    064
    065        /**
    066         * Prepares tool for a single request
    067         */
    068        public void init(Object runData)
    069        {
    070            // data = (RunData)runData;
    071        }
    072
    073        /**
    074         * Implementation of ApplicationTool interface is not needed for this
    075         * method as the tool is request scoped
    076         */
    077        public void refresh()
    078        {
    079            // empty
    080        }
    081
    082        /**
    083         * Inner class to present a nice interface to the template designer
    084         */
    085        protected class PullHelper
    086        {
    087            String omName;
    088
    089            protected PullHelper(String omName)
    090            {
    091                this.omName = omName;
    092            }
    093
    094            public Object setKey(String key)
    095                throws Exception
    096            {
    097                Object om = null;
    098
    099                String inputKey = omName + key;
    100                if (omMap.containsKey(inputKey))
    101                {
    102                    om = omMap.get(inputKey);
    103                }
    104                else
    105                {
    106                    om = omFactory.getInstance(omName).retrieve(key);
    107                    omMap.put(inputKey, om);
    108                }
    109
    110                return om;
    111            }
    112        }
    113
    114        public Object get(String omName) throws Exception
    115        {
    116            if (!pullMap.containsKey(omName))
    117            {
    118                // MT could overwrite a PullHelper, but that is not a problem
    119                // should still synchronize to avoid two threads adding at
    120                // same time
    121                synchronized (this.getClass())
    122                {
    123                    pullMap.put(omName, new OMTool.PullHelper(omName));
    124                }
    125            }
    126
    127            return pullMap.get(omName);
    128        }
    129
    130        public Object get(String omName, String key) throws Exception
    131        {
    132            return ((OMTool.PullHelper) get(omName)).setKey(key);
    133        }
    134
    135
    136        public String getName()
    137        {
    138            return "om";
    139        }
    140
    141
    142        // ****************** Recyclable implementation ************************
    143
    144        private boolean disposed;
    145
    146        /**
    147         * Recycles the object for a new client. Recycle methods with
    148         * parameters must be added to implementing object and they will be
    149         * automatically called by pool implementations when the object is
    150         * taken from the pool for a new client. The parameters must
    151         * correspond to the parameters of the constructors of the object.
    152         * For new objects, constructors can call their corresponding recycle
    153         * methods whenever applicable.
    154         * The recycle methods must call their super.
    155         */
    156        public void recycle()
    157        {
    158            disposed = false;
    159        }
    160
    161        /**
    162         * Disposes the object after use. The method is called
    163         * when the object is returned to its pool.
    164         * The dispose method must call its super.
    165         */
    166        public void dispose()
    167        {
    168            omMap.clear();
    169            // data = null;
    170            disposed = true;
    171        }
    172
    173        /**
    174         * Checks whether the recyclable has been disposed.
    175         * @return true, if the recyclable is disposed.
    176         */
    177        public boolean isDisposed()
    178        {
    179            return disposed;
    180        }
    181    }
    182
    183
    184
    185
    186
    187
    188
    189