001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.util;
018    
019    import java.net.InetAddress;
020    import java.net.ServerSocket;
021    
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    
025    /**
026     * Generator for Globally unique Strings.
027     */
028    public class UuidGenerator {
029    
030        private static final transient Log LOG = LogFactory.getLog(UuidGenerator.class); 
031        private static final String UNIQUE_STUB;
032        private static int instanceCount;
033        private static String hostName;
034        private String seed;
035        private long sequence;
036    
037        static {
038            String stub = "";
039            boolean canAccessSystemProps = true;
040            try {
041                SecurityManager sm = System.getSecurityManager();
042                if (sm != null) {
043                    sm.checkPropertiesAccess();
044                }
045            } catch (SecurityException se) {
046                canAccessSystemProps = false;
047            }
048    
049            if (canAccessSystemProps) {
050                try {
051                    hostName = InetAddress.getLocalHost().getHostName();
052                    ServerSocket ss = new ServerSocket(0);
053                    stub = "/" + ss.getLocalPort() + "-" + System.currentTimeMillis() + "/";
054                    Thread.sleep(100);
055                    ss.close();
056                } catch (Exception ioe) {
057                    LOG.warn("Could not generate unique stub", ioe);
058                }
059            } else {
060                hostName = "localhost";
061                stub = "-1-" + System.currentTimeMillis() + "-";
062            }
063            UNIQUE_STUB = generateSanitizedId(stub);
064        }
065    
066        public UuidGenerator(String prefix) {
067            synchronized (UNIQUE_STUB) {
068                this.seed = generateSanitizedId(prefix + UNIQUE_STUB + (instanceCount++) + "-");
069            }
070        }
071    
072        public UuidGenerator() {
073            this("ID-" + hostName);
074        }
075    
076        /**
077         * As we have to find the hostname as a side-affect of generating a unique
078         * stub, we allow it's easy retrevial here
079         * 
080         * @return the local host name
081         */
082        public static String getHostName() {
083            return hostName;
084        }
085    
086        /**
087         * Generate a unqiue id
088         */
089        public synchronized String generateId() {
090            return this.seed + (this.sequence++);
091        }
092    
093        /**
094         * Generate a unique ID - that is friendly for a URL or file system
095         * 
096         * @return a unique id
097         */
098        public String generateSanitizedId() {
099            return generateSanitizedId(generateId());
100        }
101    
102        /**
103         * Ensures that the id is friendly for a URL or file system
104         *
105         * @param id the unique id
106         * @return the id as file friendly id
107         */
108        public static String generateSanitizedId(String id) {
109            id = id.replace(':', '-');
110            id = id.replace('_', '-');
111            id = id.replace('.', '-');
112            id = id.replace('/', '-');
113            id = id.replace('\\', '-');
114            return id;
115        }
116    
117    }