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: */
018:
019: package org.apache.tools.ant.types.selectors.modifiedselector;
020:
021: import java.util.Iterator;
022: import java.util.Vector;
023: import java.util.Enumeration;
024: import java.util.Properties;
025: import java.io.File;
026: import java.io.BufferedInputStream;
027: import java.io.FileInputStream;
028: import java.io.BufferedOutputStream;
029: import java.io.FileOutputStream;
030:
031: /**
032: * Use java.util.Properties for storing the values.
033: * The use of this Cache-implementation requires the use of the parameter
034: * <param name="cache.cachefile" .../> for defining, where to store the
035: * properties file.
036: *
037: * The ModifiedSelector sets the <i>cachefile</i> to the default value
038: * <i>cache.properties</i>.
039: *
040: * Supported <param>s are:
041: * <table>
042: * <tr>
043: * <th>name</th><th>values</th><th>description</th><th>required</th>
044: * </tr>
045: * <tr>
046: * <td> cache.cachefile </td>
047: * <td> <i>path to file</i> </td>
048: * <td> the name of the properties file </td>
049: * <td> yes </td>
050: * </tr>
051: * </table>
052: *
053: * @version 2003-09-13
054: * @since Ant 1.6
055: */
056: public class PropertiesfileCache implements Cache {
057:
058: // ----- member variables - configuration -----
059:
060: /** Where to store the properties? */
061: private File cachefile = null;
062:
063: /** Object for storing the key-value-pairs. */
064: private Properties cache = new Properties();
065:
066: // ----- member variables - internal use -----
067:
068: /** Is the cache already loaded? Prevents from multiple load operations. */
069: private boolean cacheLoaded = false;
070:
071: /** Must the cache be saved? Prevents from multiple save operations. */
072: private boolean cacheDirty = true;
073:
074: // ----- Constructors -----
075:
076: /** Bean-Constructor. */
077: public PropertiesfileCache() {
078: }
079:
080: /**
081: * Constructor.
082: * @param cachefile set the cachefile
083: */
084: public PropertiesfileCache(File cachefile) {
085: this .cachefile = cachefile;
086: }
087:
088: // ----- Cache-Configuration -----
089:
090: /**
091: * Setter.
092: * @param file new value
093: */
094: public void setCachefile(File file) {
095: cachefile = file;
096: }
097:
098: /**
099: * Getter.
100: * @return the cachefile
101: */
102: public File getCachefile() {
103: return cachefile;
104: }
105:
106: /**
107: * This cache is valid if the cachefile is set.
108: * @return true if all is ok false otherwise
109: */
110: public boolean isValid() {
111: return (cachefile != null);
112: }
113:
114: // ----- Data Access
115:
116: /**
117: * Load the cache from underlying properties file.
118: */
119: public void load() {
120: if ((cachefile != null) && cachefile.isFile()
121: && cachefile.canRead()) {
122: try {
123: BufferedInputStream bis = new BufferedInputStream(
124: new FileInputStream(cachefile));
125: cache.load(bis);
126: bis.close();
127: } catch (Exception e) {
128: e.printStackTrace();
129: }
130: }
131: // after loading the cache is up to date with the file
132: cacheLoaded = true;
133: cacheDirty = false;
134: }
135:
136: /**
137: * Saves modification of the cache.
138: * Cache is only saved if there is one ore more entries.
139: * Because entries can not be deleted by this API, this Cache
140: * implementation checks the existence of entries before creating the file
141: * for performance optimisation.
142: */
143: public void save() {
144: if (!cacheDirty) {
145: return;
146: }
147: if ((cachefile != null)
148: && cache.propertyNames().hasMoreElements()) {
149: try {
150: BufferedOutputStream bos = new BufferedOutputStream(
151: new FileOutputStream(cachefile));
152: cache.store(bos, null);
153: bos.flush();
154: bos.close();
155: } catch (Exception e) {
156: e.printStackTrace();
157: }
158: }
159: cacheDirty = false;
160: }
161:
162: /** Deletes the cache and its underlying file. */
163: public void delete() {
164: cache = new Properties();
165: cachefile.delete();
166: cacheLoaded = true;
167: cacheDirty = false;
168: }
169:
170: /**
171: * Returns a value for a given key from the cache.
172: * @param key the key
173: * @return the stored value
174: */
175: public Object get(Object key) {
176: if (!cacheLoaded) {
177: load();
178: }
179: try {
180: return cache.getProperty(String.valueOf(key));
181: } catch (ClassCastException e) {
182: return null;
183: }
184: }
185:
186: /**
187: * Saves a key-value-pair in the cache.
188: * @param key the key
189: * @param value the value
190: */
191: public void put(Object key, Object value) {
192: cache.put(String.valueOf(key), String.valueOf(value));
193: cacheDirty = true;
194: }
195:
196: /**
197: * Returns an iterator over the keys in the cache.
198: * @return An iterator over the keys.
199: */
200: public Iterator iterator() {
201: Vector v = new java.util.Vector();
202: Enumeration en = cache.propertyNames();
203: while (en.hasMoreElements()) {
204: v.add(en.nextElement());
205: }
206: return v.iterator();
207: }
208:
209: // ----- additional -----
210:
211: /**
212: * Override Object.toString().
213: * @return information about this cache
214: */
215: public String toString() {
216: StringBuffer buf = new StringBuffer();
217: buf.append("<PropertiesfileCache:");
218: buf.append("cachefile=").append(cachefile);
219: buf.append(";noOfEntries=").append(cache.size());
220: buf.append(">");
221: return buf.toString();
222: }
223: }
|