001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU General
007: * Public License Version 2 only ("GPL") or the Common Development and Distribution
008: * License("CDDL") (collectively, the "License"). You may not use this file except in
009: * compliance with the License. You can obtain a copy of the License at
010: * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the
011: * License for the specific language governing permissions and limitations under the
012: * License. When distributing the software, include this License Header Notice in
013: * each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun
014: * designates this particular file as subject to the "Classpath" exception as
015: * provided by Sun in the GPL Version 2 section of the License file that
016: * accompanied this code. If applicable, add the following below the License Header,
017: * with the fields enclosed by brackets [] replaced by your own identifying
018: * information: "Portions Copyrighted [year] [name of copyright owner]"
019: *
020: * Contributor(s):
021: *
022: * The Original Software is NetBeans. The Initial Developer of the Original Software
023: * is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun Microsystems, Inc. All
024: * Rights Reserved.
025: *
026: * If you wish your version of this file to be governed by only the CDDL or only the
027: * GPL Version 2, indicate your decision by adding "[Contributor] elects to include
028: * this software in this distribution under the [CDDL or GPL Version 2] license." If
029: * you do not indicate a single choice of license, a recipient has the option to
030: * distribute your version of this file under either the CDDL, the GPL Version 2 or
031: * to extend the choice of license to its licensees as provided above. However, if
032: * you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then
033: * the option applies only if the new code is made subject to such option by the
034: * copyright holder.
035: */
036:
037: package org.netbeans.installer.downloader.services;
038:
039: import org.netbeans.installer.downloader.DownloadManager;
040: import org.netbeans.installer.utils.LogManager;
041: import org.netbeans.installer.utils.exceptions.ParseException;
042: import org.netbeans.installer.utils.xml.DomExternalizable;
043: import org.netbeans.installer.utils.xml.DomUtil;
044: import org.netbeans.installer.utils.xml.visitors.DomVisitor;
045: import org.netbeans.installer.utils.xml.visitors.RecursiveDomVisitor;
046: import org.w3c.dom.Document;
047: import org.w3c.dom.Element;
048: import java.io.File;
049: import java.io.IOException;
050: import java.net.URL;
051: import java.util.Map;
052: import java.util.HashMap;
053: import org.netbeans.installer.utils.ErrorManager;
054: import org.netbeans.installer.utils.StringUtils;
055:
056: /**
057: * @author Danila_Dugurov
058: */
059: public class PersistentCache {
060:
061: /////////////////////////////////////////////////////////////////////////////////
062: // Instance
063: private File stateFile;
064:
065: private final Map<URL, File> url2File = new HashMap<URL, File>();
066:
067: public PersistentCache() {
068: stateFile = new File(DownloadManager.instance.getWd(),
069: "cacheState.xml");
070: if (!stateFile.exists()) {
071: LogManager
072: .log("cache file not exist so treat it as cache is Empty");
073: } else
074: load();
075: }
076:
077: public boolean isIn(URL url) {
078: return url2File.containsKey(url) && url2File.get(url).exists();
079: }
080:
081: public File getByURL(URL url) {
082: if (!isIn(url))
083: return null;
084: return url2File.get(url);
085: }
086:
087: public void put(URL key, File file) {
088: url2File.put(key, file);
089: dump();
090: }
091:
092: public void clear() {
093: for (File file : url2File.values()) {
094: file.delete();
095: }
096: }
097:
098: public URL[] keys() {
099: return (URL[]) url2File.keySet().toArray();
100: }
101:
102: public boolean delete(URL url) {
103: if (isIn(url))
104: return url2File.get(url).delete();
105: return false;
106: }
107:
108: private void load() {
109: try {
110: Document state = DomUtil.parseXmlFile(stateFile);
111: final DomVisitor visitor = new RecursiveDomVisitor() {
112: public void visit(Element element) {
113: final String name = element.getTagName();
114: if ("cacheEntry".equals(name)) {
115: final CacheEntry entry = new CacheEntry();
116: entry.readXML(element);
117: if (entry.file.exists() && entry.file.isFile())
118: url2File.put(entry.url, entry.file);
119: } else
120: super .visit(element);
121: }
122: };
123: visitor.visit(state);
124: } catch (ParseException ex) {
125: LogManager.log(ex);
126: } catch (IOException ex) {
127: LogManager.log(ex);
128: }
129: }
130:
131: public synchronized void dump() {
132: try {
133: final Document document = DomUtil.parseXmlFile("<cache/>");
134: final Element root = document.getDocumentElement();
135: for (Map.Entry<URL, File> entry : url2File.entrySet()) {
136: final CacheEntry cacheEntry = new CacheEntry(entry);
137: DomUtil.addChild(root, cacheEntry);
138: }
139: DomUtil.writeXmlFile(document, stateFile);
140: } catch (ParseException wontHappend) {
141: LogManager.log("unparsable xml", wontHappend);
142: } catch (IOException ex) {
143: LogManager.log("i/o during loading persistentCache", ex);
144: }
145: }
146:
147: /////////////////////////////////////////////////////////////////////////////////
148: // Inner Classes
149: private static class CacheEntry implements DomExternalizable {
150:
151: private URL url;
152: private File file;
153:
154: public CacheEntry() {//before read xml
155: }
156:
157: public CacheEntry(Map.Entry<URL, File> entry) {
158: this .url = entry.getKey();
159: this .file = entry.getValue();
160: }
161:
162: public void readXML(Element element) {
163: final DomVisitor visitor = new RecursiveDomVisitor() {
164: public void visit(Element element) {
165: final String name = element.getTagName();
166: if ("file".equals(name)) {
167: file = new File(element.getTextContent());
168: } else if ("url".equals(name)) {
169: try {
170: url = StringUtils.parseUrl(element
171: .getTextContent());
172: } catch (ParseException e) {
173: ErrorManager.notifyDebug(
174: "Could not parse URL", e);
175: }
176: } else {
177: super .visit(element);
178: }
179: }
180: };
181: visitor.visit(element);
182: }
183:
184: public Element writeXML(Document document) {
185: final Element root = document.createElement("cacheEntry");
186: DomUtil.addElement(root, "file", file.getAbsolutePath());
187: DomUtil.addElement(root, "url", url.toString());
188: return root;
189: }
190: }
191: }
|