001    package org.apache.turbine.services.uniqueid;
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.security.MessageDigest;
025    
026    
027    import org.apache.commons.codec.binary.Base64;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    
031    import org.apache.turbine.Turbine;
032    import org.apache.turbine.services.InitializationException;
033    import org.apache.turbine.services.TurbineBaseService;
034    import org.apache.turbine.util.GenerateUniqueId;
035    
036    /**
037     * <p> This is an implementation of {@link UniqueIdService}.
038     *
039     * @author <a href="mailto:Rafal.Krzewski@e-point.pl">Rafal Krzewski</a>
040     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
041     * @version $Id: TurbineUniqueIdService.java 1066925 2011-02-03 19:44:37Z ludwig $
042     */
043    public class TurbineUniqueIdService
044            extends TurbineBaseService
045            implements UniqueIdService
046    {
047        /** Logging */
048        private static Log log = LogFactory.getLog(TurbineUniqueIdService.class);
049    
050        /** The identifier of this instance of turbine. */
051        protected static String turbineId = "UNKNOWN";
052    
053        protected static String turbineURL = "UNKNOWN";
054    
055        protected static int counter;
056    
057    
058        /**
059         * <p> Initializes the service upon first Turbine.doGet()
060         * invocation.
061         */
062        @Override
063        public void init()
064                throws InitializationException
065        {
066            try
067            {
068                // This might be a problem if the unique Id Service runs
069                // before Turbine got its first request. In this case,
070                // getDefaultServerData will return just a dummy value
071                // which is the same for all instances of Turbine.
072                //
073                // @todo This needs definitely further working.
074                String url = Turbine.getDefaultServerData().toString();
075    
076                MessageDigest md = MessageDigest.getInstance("MD5");
077                byte [] bytesId = md.digest(url.getBytes("UTF-8"));
078                turbineId = new String(Base64.encodeBase64(bytesId));
079    
080                log.info("This is Turbine instance running at: " + url);
081                log.info("The instance id is #" + turbineId);
082                setInit(true);
083            }
084            catch (Exception e)
085            {
086                throw new InitializationException(
087                        "Could not initialize TurbineUniqueId Service", e);
088            }
089        }
090    
091        /**
092         * <p> Writes a message to the log upon system shutdown.
093         */
094        @Override
095        public void shutdown()
096        {
097            log.info("Turbine instance running at " + turbineURL + " shutting down.");
098        }
099    
100        /**
101         * <p> Returns an identifier of this Turbine instance that is unique
102         * both on the server and worldwide.  This identifier is computed
103         * as an MD5 sum of the URL (including schema, address, port if
104         * different that 80/443 respecively, context and servlet name).
105         * There is an overwhelming probalility that this id will be
106         * different that all other Turbine instances online.
107         *
108         * @return A String with the instance identifier.
109         */
110        public String getInstanceId()
111        {
112            return turbineId;
113        }
114    
115        /**
116         * <p> Returns an identifier that is unique within this turbine
117         * instance, but does not have random-like apearance.
118         *
119         * @return A String with the non-random looking instance
120         * identifier.
121         */
122        public String getUniqueId()
123        {
124            int current;
125            synchronized (TurbineUniqueIdService.class)
126            {
127                current = counter++;
128            }
129            String id = Integer.toString(current);
130    
131            // If you manage to get more than 100 million of ids, you'll
132            // start getting ids longer than 8 characters.
133            if (current < 100000000)
134            {
135                id = ("00000000" + id).substring(id.length());
136            }
137            return id;
138        }
139    
140        /**
141         * <p> Returns a unique identifier that looks like random data.
142         *
143         * @return A String with the random looking instance identifier.
144         */
145        public String getPseudorandomId()
146        {
147            return GenerateUniqueId.getIdentifier();
148        }
149    }