A java.util.Properties class that will check a file or URL for changes periodically : Properties « Development Class « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Class
8. Collections Data Structure
9. Data Type
10. Database SQL JDBC
11. Design Pattern
12. Development Class
13. EJB3
14. Email
15. Event
16. File Input Output
17. Game
18. Generics
19. GWT
20. Hibernate
21. I18N
22. J2EE
23. J2ME
24. JDK 6
25. JNDI LDAP
26. JPA
27. JSP
28. JSTL
29. Language Basics
30. Network Protocol
31. PDF RTF
32. Reflection
33. Regular Expressions
34. Scripting
35. Security
36. Servlets
37. Spring
38. Swing Components
39. Swing JFC
40. SWT JFace Eclipse
41. Threads
42. Tiny Application
43. Velocity
44. Web Services SOA
45. XML
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java » Development Class » PropertiesScreenshots 
A java.util.Properties class that will check a file or URL for changes periodically
    
/*
 * RefreshingProperties.java
 *
 * Created on November 11, 2005, 10:15 PM
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import java.net.URL;

import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * This is a java.util.Properties class that will check a file or URL for changes
 * periodically. It has a threaded and non-threaded mode, and will reload a URL
 * every recheck time, or inspect the last modified date on a file on check.
 @author <a href="mailto:cooper@screaming-penguin.com">Robert "kebernet" Cooper</a>
 @version $Revision: 1.4 $
 */
public class RefreshingProperties extends Properties {
    /**
     * DOCUMENT ME!
     */
    private static final Logger LOG = Logger.getLoggerRefreshingProperties.class.getCanonicalName() );
    
    
    /**
     * DOCUMENT ME!
     */
    private ArrayList<RefreshingProperties.RefreshListener> listeners = new ArrayList<RefreshingProperties.RefreshListener>();
    
    /**
     * DOCUMENT ME!
     */
    private Thread updater;
    
    /**
     * DOCUMENT ME!
     */
    private URL url;
    
    /**
     * DOCUMENT ME!
     */
    private long lastCheck;
    
    /**
     * DOCUMENT ME!
     */
    private long recheckTime = 60 1000;
    
    private boolean loading = false;
    
    private ArrayList<RefreshingProperties> augmentProps = new ArrayList<RefreshingProperties>();
    private ArrayList<RefreshingProperties> overrideProps = new ArrayList<RefreshingProperties>();
    
    private boolean noImportMode = false;
    
    /**
     * Creates a new RefreshingProperties object.
     * This constructor will use the default settings of threaded mode and recheck at 5 minutes.
     @param url URL to read from.
     @throws IOException Thrown on read errors.
     */
    public RefreshingProperties(URL urlthrows IOException {
        init(url,recheckTime,true);
    }
    
    /**
     * Creates a new RefreshingProperties object.
     * This will use the default recheck at 5 minutes.
     @param url URL to read from
     @param useThread Indicates whether the check should run in threaded or non-threaded road.
     @throws IOException Thrown on read errors.
     */
    public RefreshingProperties(URL url,boolean useThreadthrows IOException {
        init(url,recheckTime,useThread);
    }
    
    /**
     * Creates a new RefreshingProperties object.
     * Uses the default threaded mode.
     @param recheckTime number of milliseconds between rechecks
     @param url URL to load from
     @throws IOException Thrown on read errors.
     */
    public RefreshingProperties(URL url,long recheckTimethrows IOException {
        init(url,recheckTime,true);
    }
    
    /**
     * Creates a new RefreshingProperties object.
     @param url URL to read from
     @param recheckTime recheck time in milliseconds
     @param useThread Whether the recheck should be threaded or unthreaded.
     @throws IOException Thrown on read errors.
     */
    public RefreshingProperties(URL url,long recheckTime,boolean useThreadthrows IOException {
        init(url,recheckTime,useThread);
    }
    
    /**
     * Calls the <tt>Hashtable</tt> method <code>put</code>. Provided for
     * parallelism with the <tt>getProperty</tt> method. Enforces use of
     * strings for property keys and values. The value returned is the
     * result of the <tt>Hashtable</tt> call to <code>put</code>.
     *
     @param key the key to be placed into this property list.
     @param value the value corresponding to <tt>key</tt>.
     @return     the previous value of the specified key in this property
     *             list, or <code>null</code> if it did not have one.
     @see #getProperty
     @since    1.2
     */
    public Object setProperty(String key,String value) {
        Object retValue;
        threadCheck();
        retValue = super.setProperty(key,value);
        
        return retValue;
    }
    
    /**
     * Searches for the property with the specified key in this property list.
     * If the key is not found in this property list, the default property list,
     * and its defaults, recursively, are then checked. The method returns
     * <code>null</code> if the property is not found.
     *
     @param   key   the property key.
     @return  the value in this property list with the specified key value.
     @see     #setProperty
     @see     #defaults
     */
    public String getProperty(String key) {
        threadCheck();
        
        String retValue;
        retValue = super.getProperty(key);
        
        return retValue;
    }
    
    /**
     * Searches for the property with the specified key in this property list.
     * If the key is not found in this property list, the default property list,
     * and its defaults, recursively, are then checked. The method returns the
     * default value argument if the property is not found.
     *
     @param   key            the hashtable key.
     @param   defaultValue   a default value.
     *
     @return  the value in this property list with the specified key value.
     @see     #setProperty
     @see     #defaults
     */
    public String getProperty(String key,String defaultValue) {
        String retValue;
        threadCheck();
        retValue = super.getProperty(key,defaultValue);
        
        return retValue;
    }
    
    /**
     * DOCUMENT ME!
     *
     @param listener DOCUMENT ME!
     */
    public void addRefreshListener(RefreshingProperties.RefreshListener listener) {
        this.listeners.add(listener);
    }
    
    /**
     * Creates a shallow copy of this hashtable. All the structure of the
     * hashtable itself is copied, but the keys and values are not cloned.
     * This is a relatively expensive operation.
     *
     @return  a clone of the hashtable.
     */
    public Object clone() {
        Object retValue;
        threadCheck();
        retValue = super.clone();
        
        return retValue;
    }
    
    /**
     * Tests if some key maps into the specified value in this hashtable.
     * This operation is more expensive than the <code>containsKey</code>
     * method.<p>
     *
     * Note that this method is identical in functionality to containsValue,
     * (which is part of the Map interface in the collections framework).
     *
     @return <code>true</code> if and only if some key maps to the
     *             <code>value</code> argument in this hashtable as
     *             determined by the <tt>equals</tt> method;
     *             <code>false</code> otherwise.
     @see #containsKey(Object)
     @see #containsValue(Object)
     @see Map
     @param value a value to search for.
     */
    public boolean contains(Object value) {
        threadCheck();
        
        boolean retValue;
        
        retValue = super.contains(value);
        
        return retValue;
    }
    
    /**
     * Tests if the specified object is a key in this hashtable.
     *
     @return <code>true</code> if and only if the specified object
     *          is a key in this hashtable, as determined by the
     *          <tt>equals</tt> method; <code>false</code> otherwise.
     @see #contains(Object)
     @param key possible key.
     */
    public boolean containsKey(Object key) {
        boolean retValue;
        threadCheck();
        retValue = super.containsKey(key);
        
        return retValue;
    }
    
    /**
     * Returns true if this Hashtable maps one or more keys to this value.<p>
     *
     * Note that this method is identical in functionality to contains
     * (which predates the Map interface).
     *
     @return <tt>true</tt> if this map maps one or more keys to the
     *         specified value.
     @see Map
     @since 1.2
     @param value value whose presence in this Hashtable is to be tested.
     */
    public boolean containsValue(Object value) {
        boolean retValue;
        threadCheck();
        retValue = super.containsValue(value);
        
        return retValue;
    }
    
    /**
     * Returns an enumeration of the values in this hashtable.
     * Use the Enumeration methods on the returned object to fetch the elements
     * sequentially.
     *
     @return  an enumeration of the values in this hashtable.
     @see     java.util.Enumeration
     @see     #keys()
     @see        #values()
     @see        Map
     */
    public java.util.Enumeration<Object> elements() {
        java.util.Enumeration retValue;
        threadCheck();
        retValue = super.elements();
        
        return retValue;
    }
    
    /**
     * Returns a Set view of the entries contained in this Hashtable.
     * Each element in this collection is a Map.Entry.  The Set is
     * backed by the Hashtable, so changes to the Hashtable are reflected in
     * the Set, and vice-versa.  The Set supports element removal
     * (which removes the corresponding entry from the Hashtable),
     * but not element addition.
     *
     @return a set view of the mappings contained in this map.
     @see   Map.Entry
     @since 1.2
     */
    public java.util.Set<java.util.Map.Entry<Object,Object>> entrySet() {
        java.util.Set retValue;
        threadCheck();
        retValue = super.entrySet();
        
        return retValue;
    }
    
    /**
     * Returns the value to which the specified key is mapped in this hashtable.
     *
     @return the value to which the key is mapped in this hashtable;
     *          <code>null</code> if the key is not mapped to any value in
     *          this hashtable.
     @see #put(Object, Object)
     @param key a key in the hashtable.
     */
    public Object get(Object key) {
        threadCheck();
        
        Object retValue;
        forRefreshingProperties over : this.overrideProps ){
            Object overValue = over.get(key);
            ifoverValue != null){
                return overValue;
            }
        }
        retValue = super.get(key);
        ifretValue == null ){
            forRefreshingProperties aug : this.augmentProps ){
                Object augValue = aug.getkey );
                ifaugValue != null ){
                    retValue = augValue;
                    break;
                }
            }
        }
        return retValue;
    }
    
    /**
     * Returns a Set view of the keys contained in this Hashtable.  The Set
     * is backed by the Hashtable, so changes to the Hashtable are reflected
     * in the Set, and vice-versa.  The Set supports element removal
     * (which removes the corresponding entry from the Hashtable), but not
     * element addition.
     *
     @return a set view of the keys contained in this map.
     @since 1.2
     */
    public java.util.Set<Object> keySet() {
        java.util.Set retValue;
        threadCheck();
        retValue = super.keySet();
        forRefreshingProperties props : this.augmentProps ){
            retValue.addAllprops.keySet() );
        }
        forRefreshingProperties props : this.overrideProps ){
            retValue.addAllprops.keySet() );
        }
        return retValue;
    }
    
    /**
     * Returns an enumeration of the keys in this hashtable.
     *
     @return  an enumeration of the keys in this hashtable.
     @see     Enumeration
     @see     #elements()
     @see        #keySet()
     @see        Map
     */
    public java.util.Enumeration<Object> keys() {
        java.util.Enumeration retValue;
        threadCheck();
        retValue = (new Vectorthis.keySet() )).elements();        
        return retValue;
    }
    
    /**
     * Returns an enumeration of all the keys in this property list,
     * including distinct keys in the default property list if a key
     * of the same name has not already been found from the main
     * properties list.
     *
     @return  an enumeration of all the keys in this property list, including
     *          the keys in the default property list.
     @see     java.util.Enumeration
     @see     java.util.Properties#defaults
     */
    public java.util.Enumeration<Object> propertyNames() {
        java.util.Enumeration retValue;
        threadCheck();
        retValue = super.propertyNames();
        
        return retValue;
    }
    
    /**
     * Maps the specified <code>key</code> to the specified
     * <code>value</code> in this hashtable. Neither the key nor the
     * value can be <code>null</code>. <p>
     *
     * The value can be retrieved by calling the <code>get</code> method
     * with a key that is equal to the original key.
     *
     @return the previous value of the specified key in this hashtable,
     *             or <code>null</code> if it did not have one.
     @see Object#equals(Object)
     @see #get(Object)
     @param key the hashtable key.
     @param value the value.
     */
    public Object put(Object key,Object value) {
        threadCheck();
        if!this.noImportMode && key instanceof String && ((Stringkey ).startsWith("@import.") ){
            String keyString = ((Stringkey );
            String importType = keyString.substring8, keyString.lastIndexOf(".") );
            ImportRefreshListener irl = null;
            
            ifimportType.equals("override") ){
                irl = new ImportRefreshListenerthis, true );
            else ifimportType.equals("augment") ) {
                irl = new ImportRefreshListenerthis, false );
            else {
                throw new RuntimeException("Import type: "+importType+" unknown.");
            }
            try{
                boolean useThread = (this.updater != null );
                RefreshingProperties importedProp = new RefreshingPropertiesnew URLthis.url, (Stringvalue )this.recheckTime, useThread );
                ifirl.clobber ){
                    this.overrideProps.addimportedProp );
                else {
                    this.augmentProps.addimportedProp );
                }
                importedProp.addRefreshListenerirl );
                this.importLoadimportedProp, irl.clobber );
            catch(Exception e){
                throw new RuntimeException("Exception creaing child properties", e);
            }
        }
        return super.put(key,value);
    }
    
    /**
     * Copies all of the mappings from the specified Map to this Hashtable
     * These mappings will replace any mappings that this Hashtable had for any
     * of the keys currently in the specified Map.
     *
     @since 1.2
     @param t Mappings to be stored in this map.
     */
    public void putAll(java.util.Map t) {
        threadCheck();
        super.putAll(t);
    }
    
    /**
     * Removes the key (and its corresponding value) from this
     * hashtable. This method does nothing if the key is not in the hashtable.
     *
     @return the value to which the key had been mapped in this hashtable,
     *          or <code>null</code> if the key did not have a mapping.
     @param key the key that needs to be removed.
     */
    public Object remove(Object key) {
        threadCheck();
        
        Object retValue;
        
        retValue = super.remove(key);
        
        return retValue;
    }
    
    /**
     * DOCUMENT ME!
     *
     @param listener DOCUMENT ME!
     */
    public void removeRefreshListener(RefreshingProperties.RefreshListener listener) {
        this.listeners.remove(listener);
    }
    
    /**
     * Returns a Collection view of the values contained in this Hashtable.
     * The Collection is backed by the Hashtable, so changes to the Hashtable
     * are reflected in the Collection, and vice-versa.  The Collection
     * supports element removal (which removes the corresponding entry from
     * the Hashtable), but not element addition.
     *
     @return a collection view of the values contained in this map.
     @since 1.2
     */
    public java.util.Collection<Object> values() {
        java.util.Collection retValue;
        threadCheck();
        ArrayList values = new ArrayList();
        forObject key : this.keySet() ){
            values.addthis.get(key ) );
        }
        
        return values;
    }
    
    /**
     * DOCUMENT ME!
     */
    private void check() {
        try {
            if(this.url.getProtocol().equals("file") ) {
                File f = new File(this.url.getFile());
                iff.lastModified() this.lastCheck ){
                    this.load();
                }
            else if!this.url.getProtocol().equals("file"&& System.currentTimeMillis() this.lastCheck > this.recheckTime ){
                this.load();
            }
            this.lastCheck = System.currentTimeMillis();
        catch(IOException e) {
            RefreshingProperties.LOG.log(Level.WARNING,"Exception reloading properies.",e);
        }
        
    }
    
    private void importLoadRefreshingProperties source, boolean clobber ){
        Enumeration keys = source.keys();
        whilekeys.hasMoreElements() ){
            String key = (Stringkeys.nextElement();
            ifclobber || this.getPropertykey == null )
                this.putkey, source.getPropertykey ) );
        }
        this.fireEvents();
        
    }
    
    
    /**
     * DOCUMENT ME!
     *
     @param url DOCUMENT ME!
     @param recheckTime DOCUMENT ME!
     @param useThread DOCUMENT ME!
     *
     @throws IOException DOCUMENT ME!
     */
    private void init(URL url,long recheckTime,boolean useThreadthrows IOException {
        this.url = url;
        this.recheckTime = recheckTime;
        if(useThread) {
            this.updater = new UpdateThread(this);
            this.updater.start();
        }
        
        this.check();
    }
    
    /**
     * DOCUMENT ME!
     *
     @throws IOException DOCUMENT ME!
     */
    private void load() throws IOException {
        this.loading = true;
        InputStream is = null;
        super.clear();
        is = this.url.openStream();
        super.load(is);
        is.close();
        RefreshingProperties.LOG.log(Level.FINEST,"Loading of " this.url + " at " new Date());
        
        this.fireEvents();
        
        this.loading = false;
    }
    
    private void fireEvents(){
        RefreshingProperties.ReloadEvent event = new ReloadEvent(this, this.url,System.currentTimeMillis());
        
        for(RefreshingProperties.RefreshListener listener : this.listeners) {
            listener.propertiesRefreshNotify(event);
        }
    }
    
    /**
     * DOCUMENT ME!
     */
    private void threadCheck() {
        if(!this.loading && this.updater == null) {
            check();
        }
    }
    
    /**
     * DOCUMENT ME!
     *
     @author $author$
     @version $Revision: 1.4 $
     */
    public static interface RefreshListener {
        /**
         * DOCUMENT ME!
         *
         @param event DOCUMENT ME!
         */
        public void propertiesRefreshNotify(RefreshingProperties.ReloadEvent event);
    }
    
    /**
     * DOCUMENT ME!
     *
     @author $author$
     @version $Revision: 1.4 $
     */
    public static class ReloadEvent {
        /**
         * DOCUMENT ME!
         */
        private URL url;
        
        /**
         * DOCUMENT ME!
         */
        private long time;
        
        private RefreshingProperties source;
        /**
         * Creates a new ReloadEvent object.
         *
         @param url DOCUMENT ME!
         @param time DOCUMENT ME!
         */
        public ReloadEvent(RefreshingProperties source, URL url,long time) {
            this.setSource(source);
            this.url = url;
            this.time = time;
        }
        
        /**
         * DOCUMENT ME!
         *
         @param time DOCUMENT ME!
         */
        public void setTime(long time) {
            this.time = time;
        }
        
        /**
         * DOCUMENT ME!
         *
         @return DOCUMENT ME!
         */
        public long getTime() {
            return time;
        }
        
        /**
         * DOCUMENT ME!
         *
         @param url DOCUMENT ME!
         */
        public void setUrl(URL url) {
            this.url = url;
        }
        
        /**
         * DOCUMENT ME!
         *
         @return DOCUMENT ME!
         */
        public URL getUrl() {
            return url;
        }
        
        public RefreshingProperties getSource() {
            return source;
        }
        
        public void setSource(RefreshingProperties source) {
            this.source = source;
        }
    }
    
    /**
     * DOCUMENT ME!
     *
     @author $author$
     @version $Revision: 1.4 $
     */
    private class UpdateThread extends Thread {
        /**
         * DOCUMENT ME!
         */
        private RefreshingProperties props;
        
        /**
         * Creates a new UpdateThread object.
         *
         @param props DOCUMENT ME!
         */
        UpdateThread(RefreshingProperties props) {
            this.setDaemon(true);
            this.props = props;
        }
        
        /**
         * DOCUMENT ME!
         */
        public void run() {
            boolean running = true;
            
            while(running) {
                props.LOG.log(Level.FINEST,"RefeshingProperties thread check of " + props.url + " at " new Date());
                
                try {
                    Thread.sleep(props.recheckTime);
                catch(InterruptedException e) {
                    RefreshingProperties.LOG.log(Level.WARNING,"Interrupted.",e);
                }
                
                props.check();
            }
        }
    }
    
    private class ImportRefreshListener implements RefreshListener {
        private RefreshingProperties target;
        private boolean clobber;
        ImportRefreshListenerRefreshingProperties target, boolean clobber ){
            this.target = target;
            this.clobber = clobber;
        }
        
        public void propertiesRefreshNotify(ReloadEvent event) {
            target.fireEvents();
        }
    }
}

   
    
    
    
  
Related examples in the same category
1. Read a set of properties from the received input stream, strip off any excess white space that exists in those property values,
2. Copy a set of properties from one Property to another.
3. Sorts property list and print out each key=value pair prepended with specific indentation.
4. Sorts a property list and turns the sorted list into a string.
5. A utility class for replacing properties in strings.
6. Property Loader
7. Property access utility methods
8. Represents a persistent set of properties
9. Converts specified map to java.util.Properties
10. Encapsulates java.util.Properties to add java primitives and some other java classes
11. Load and save properties to files.
12. Adds new properties to an existing set of properties
13. Extracts a specific property key subset from the known properties
14. Observable Properties
15. Merge Properties Into Map
16. XML configuration management
17. JDOM based XML properties
18. XML Properties
19. Converts Unicode into something that can be embedded in a java properties file
20. Create Properties from String array
21. Task to overwrite Properties
22. Gets strong-type-value property from a standard Properties
23. The properties iterator iterates over a set of enumerated properties.
24. An utility class to ease up using property-file resource bundles.
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.