Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright 2010 Oracle and/or its affiliates. All rights reserved.
   *
   * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   * Other names may be trademarks of their respective owners.
   *
   * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common
  * Development and Distribution License("CDDL") (collectively, the
  * "License"). You may not use this file except in compliance with the
  * License. You can obtain a copy of the License at
  * http://www.netbeans.org/cddl-gplv2.html
  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  * specific language governing permissions and limitations under the
  * License.  When distributing the software, include this License Header
  * Notice in each file and include the License file at
  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the GPL Version 2 section of the License file that
  * accompanied this code. If applicable, add the following below the
  * License Header, with the fields enclosed by brackets [] replaced by
  * your own identifying information:
  * "Portions Copyrighted [year] [name of copyright owner]"
  *
  * If you wish your version of this file to be governed by only the CDDL
  * or only the GPL Version 2, indicate your decision by adding
  * "[Contributor] elects to include this software in this distribution
  * under the [CDDL or GPL Version 2] license." If you do not indicate a
  * single choice of license, a recipient has the option to distribute
  * your version of this file under either the CDDL, the GPL Version 2 or
  * to extend the choice of license to its licensees as provided above.
  * However, if you add GPL Version 2 code and therefore, elected the GPL
  * Version 2 license, then the option applies only if the new code is
  * made subject to such option by the copyright holder.
  *
  * Contributor(s):
  *
  * Portions Copyrighted 2009 Sun Microsystems, Inc.
  */
 
 package org.netbeans.modules.bugtracking.ui.issue.cache;
 
 import java.io.File;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;

Author(s):
Tomas Stupka
 
 class IssueStorage {
 
     private static IssueStorage instance;
     private File storage;
     private static final String STORAGE_FILE  = "storage";              // NOI18N
     private static final String STORAGE_VERSION_1_0 = "1.0";            // NOI18N
     private static final String STORAGE_VERSION_1_1 = "1.1";            // NOI18N
     private static final String STORAGE_VERSION = ;  // NOI18N
     private String QUERY_ARCHIVED_SUFIX = ".qa";                        // NOI18N
     private String QUERY_SUFIX = ".q";                                  // NOI18N
     private String ISSUE_SUFIX = ".i";                                  // NOI18N
 
     private FileLocks fileLocks = new FileLocks();
 
     private IssueStorage() { }
 
     public static IssueStorage getInstance() {
        if( == null) {
             = new IssueStorage();
            .initStorage();
        }
        return ;
    }
    private void initStorage() {
         = getStorageRootFile();
        if(!.exists()) {
            .mkdirs();
        }
        writeStorage();
        Task t = BugtrackingManager.getInstance().getRequestProcessor().create(new Runnable() {
            public void run() {
                cleanup();
            }
        });
        t.schedule(0);
    }
    long getReferenceTime(String nameSpacethrows IOException {
        File folder = getNameSpaceFolder(nameSpace);
        File data = new File(folder"data");
        
        FileLock lock = .getLock(data);
        try {
            synchronized(lock) {
                long ret = -1;
                if(data.exists()) {
                    DataInputStream is = null;
                    try {
                        is = getDataInputStream(data);
                        ret = is.readLong();
                        return ret;
                    } catch (EOFException ex) {
                        ..log(.data.getAbsolutePath(), ex);
                        return -1;
                    } catch (InterruptedException ex) {
                        ..log(.nullex);
                        IOException ioe = new IOException(ex.getMessage());
                        ioe.initCause(ex);
                        throw ioe;
                    } finally {
                        if(..isLoggable(.)) {
                            String dateString = ret > -1 ? new SimpleDateFormat().format(new Date(ret)) : "null";   // NOI18N
                            ..log(."finished reading greference time {0} - {1}"new Object[] {nameSpacedateString}); // NOI18N
                        }
                        try { if(is != nullis.close(); } catch (IOException e) {}
                    }
                } else {
                    data.createNewFile();
                    ret = System.currentTimeMillis();
                    DataOutputStream os = null;
                    try {
                        os = getDataOutputStream(datafalse);
                        os.writeLong(ret);
                        return ret;
                    } catch (InterruptedException ex) {
                        ..log(.nullex);
                        IOException ioe = new IOException(ex.getMessage());
                        ioe.initCause(ex);
                        throw ioe;
                    } finally {
                        if(..isLoggable(.)) {
                            String dateString = ret > -1 ? new SimpleDateFormat().format(new Date(ret)) : "null";   // NOI18N
                            ..log(."finished writing greference time {0} - {1}"new Object[] {nameSpacedateString}); // NOI18N
                        }
                        try { if(os != nullos.close(); } catch (IOException e) {}
                    }
                }
            }
        } finally {
            if(lock != null) { lock.release(); }
        }
    }
    public void storeIssue(String nameSpaceIssueEntry entrythrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start storing issue {0} - {1}"new Object[] {nameSpaceentry.getId()}); // NOI18N
        InputStream is = null;
        DataOutputStream dos = null;
        FileLock lock = null;
        try {
            File issueFile = getIssueFile(getNameSpaceFolder(nameSpace), entry.getId());
            lock = .getLock(issueFile);
            synchronized(lock) {
                dos = getIssueOutputStream(issueFile);
                if(dos == null) {
                    return;
                }
                dos.writeBoolean(entry.wasSeen());
                dos.writeLong(entry.getLastSeenModified());
                dos.writeInt(entry.getLastUnseenStatus());
                if(entry.getSeenAttributes() != null) {
                    for(Entry<StringStringe : entry.getSeenAttributes().entrySet()) {
                        writeString(dose.getKey());
                        writeString(dose.getValue());
                    }
                }
            }
        } catch (InterruptedException ex) {
            ..log(.nullex);
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            try { if(dos != nulldos.close(); } catch (IOException e) {}
            try { if(is != nullis.close(); } catch (IOException e) {}
            if(lock != null) {
                lock.release();
            }
            ..log(."finished storing issue {0} - {1}"new Object[] {nameSpaceentry.getId()}); // NOI18N
        }
    }
    public void readIssue(String nameSpaceIssueEntry entrythrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start reading issue {0} - {1}"new Object[] {nameSpaceentry.getId()}); // NOI18N
        DataInputStream is = null;
        FileLock lock = null;
        try {
            File issueFile = getIssueFile(getNameSpaceFolder(nameSpace), entry.getId());
            lock = .getLock(issueFile);
            synchronized(lock) {
                is = getIssueInputStream(issueFile);
                if(is == null) {
                    return;
                }
                Map<StringStringm = new HashMap<StringString>();
                boolean seen = is.readBoolean();
                long lastModified = -1;
                int lastStatus = .;
                if(!.equals()) {
                    lastModified = is.readLong();
                    lastStatus = is.readInt();
                }
                while(true) {
                    try {
                        String key = readString(is);
                        String value = readString(is);
                        m.put(keyvalue);
                    } catch (EOFException e) { // XXX
                        break;
                    }
                }
                entry.setSeenAttributes(m);
                entry.setSeen(seen);
                entry.setLastSeenModified(lastModified);
                entry.setLastUnseenStatus(lastStatus);
            }
        } catch (InterruptedException ex) {
            ..log(.nullex);
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            if(is != nulltry { is.close(); } catch(IOException e) {}
            if(lock != null) {
                lock.release();
            }
            ..log(."finished reading issue {0} - {1}"new Object[] {nameSpaceentry.getId()}); // NOI18N
        }
    }
    public List<StringreadQuery(String nameSpaceString queryNamethrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start reading query {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        DataInputStream dis = null;
        FileLock lock = null;
        try {
            File folder = getNameSpaceFolder(nameSpace);
            if(!folder.exists()) return Collections.emptyList();
            File f = getQueryFile(folderqueryNamefalse);
            lock = .getLock(f);
            synchronized(lock) {
                dis = getQueryInputStream(f);
                return readQuery(dis);
            }
        } catch (InterruptedException ex) {
            ..log(.nullex);
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            ..log(."finished reading query {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
            if(dis != nulltry { dis.close(); } catch(IOException e) {}
            if(lock != null) {
                lock.release();
            }
        }
    }
    private List<StringreadQuery(DataInputStream disthrows IOException {
        if(dis == nullreturn Collections.emptyList();
        List<Stringids = new ArrayList<String>();
        while(true) {
            String id = null;
            try {
                id = readString(dis);
            } catch (EOFException e) {
                    break;
            }
            ids.add(id);
        }
        return ids;
    }
    long getQueryTimestamp(String nameSpaceString name) {
        File folder = getNameSpaceFolder(nameSpace);
        File file = new File(folder, TextUtils.encodeURL(name) + );
        return file.lastModified();
    }
    public Map<StringLongreadArchivedQueryIssues(String nameSpaceString queryNamethrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start reading archived query issues {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        long now = System.currentTimeMillis();
        long ttl = BugtrackingConfig.getInstance().getArchivedIssuesTTL() * 1000 * 60 * 60 * 24;
        FileLock lock = null;
        DataInputStream dis = null;
        try {
            File folder = getNameSpaceFolder(nameSpace);
            if(!folder.exists()) return Collections.emptyMap();
            File f = getQueryFile(folderqueryNametrue);
            lock = .getLock(f);
            synchronized(lock) {
                dis = getQueryInputStream(f);
                if(dis == nullreturn Collections.emptyMap();
                Map<StringLongids = readArchivedQueryIssues(dis);
                Iterator<Stringit = ids.keySet().iterator();
                while(it.hasNext()) {
                    String id = it.next();
                    long ts = ids.get(id);
                    if(ts < now - ttl) {
                        it.remove();
                    }
                }
                return ids;
            }
        } catch (InterruptedException ex) {
            ..log(.nullex);
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            ..log(."finished reading archived query issues {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
            if(dis != nulltry { dis.close(); } catch(IOException e) {}
            if(lock != null) {
                lock.release();
            }
        }
    }
    private Map<StringLongreadArchivedQueryIssues(DataInputStream disthrows IOException {
        if(dis == nullreturn Collections.emptyMap();
        Map<StringLongids = new HashMap<StringLong>();
        while(true) {
            String id = null;
            long ts = -1;
            try {
                id = readString(dis);
                ts = dis.readLong();
                ids.put(idts);
            } catch (EOFException e) {
                break;
            }
        }
        return ids;
    }
    public void removeQuery(String nameSpaceString queryNamethrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start removing query {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        FileLock lock = null;
        try {
            File folder = getNameSpaceFolder(nameSpace);
            File query = getQueryFile(folderqueryNamefalse);
            if(query.exists()) {
                lock = .getLock(query);
                try {
                    synchronized(lock) {
                        BugtrackingUtil.deleteRecursively(query);
                    }
                } finally {
                    if(lock != null) { lock.release(); }
                }
            }
            lock = null;
            File queryArchived = getQueryFile(folderqueryNametrue);
            if(queryArchived.exists()) {
                lock = .getLock(queryArchived);
                try {
                    synchronized(lock) {
                        BugtrackingUtil.deleteRecursively(queryArchived);
                    }
                } finally {
                    if(lock != null) {lock.release();}
                }
            }
        } finally {
            ..log(."finished removing query {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        }
    }
    void storeQuery(String nameSpaceString queryNameString[] idsthrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start storing query issues {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        FileLock lock = null;
        DataOutputStream dos = null;
        try {
            File folder = getNameSpaceFolder(nameSpace);
            File f = getQueryFile(folderqueryNamefalse);
            lock = .getLock(f);
            synchronized(lock) {
                dos = getQueryOutputStream(f);
                for (String id : ids) {
                    writeString(dosid);
                }
                dos.flush();
            }
        } catch (InterruptedException ex) {
            ..log(.nullex);
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            ..log(."finished storing query issues {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
            if(dos != nulltry { dos.close(); } catch(IOException e) {}
            if(lock != null) {
                lock.release();
            }
        }
    }
    void storeArchivedQueryIssues(String nameSpaceString queryNameString[] idsthrows IOException {
        assert !SwingUtilities.isEventDispatchThread() : "should not access the issue storage in awt"// NOI18N
        ..log(."start storing archived query issues {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        long now = System.currentTimeMillis();
        Map<StringLongarchived = readArchivedQueryIssues(nameSpacequeryName);
        DataOutputStream dos = null;
        FileLock lock = null;
        try {
            File folder = getNameSpaceFolder(nameSpace);
            File f = getQueryFile(folderqueryNametrue);
            lock = .getLock(f);
            synchronized(lock) {
                dos = getQueryOutputStream(f);
                for (String id : ids) {
                    writeString(dosid);
                    Long ts = archived.get(id);
                    if(ts != null && ts.longValue() != -1) {
                        dos.writeLong(ts);
                    } else {
                        dos.writeLong(now);
                    }
                }
                dos.flush();
            }
        } catch (InterruptedException ex) {
            ..log(.nullex);
            IOException ioe = new IOException(ex.getMessage());
            ioe.initCause(ex);
            throw ioe;
        } finally {
            try { if(dos != nulldos.close(); } catch (IOException e) {}
            if(lock != null) {
                lock.release();
            }
            ..log(."finished storing archived query issues {0} - {1}"new Object[] {nameSpacequeryName}); // NOI18N
        }
    }
    void cleanup() {
        try {
            ..log(."starting bugtrackig storage cleanup"); // NOI18N
            File root = getStorageRootFile();
            File[] repos = root.listFiles();
            if(repos == null) {
                return;
            }
            for (File repo : repos) {
                cleanup(repo);
            }
        } finally {
            ..log(."finnished bugtrackig storage cleanup"); // NOI18N
        }
    }
    void cleanup(String namespace) {
        try {
            ..log(."starting bugtrackig storage cleanup for {0}"new Object[] {namespace}); // NOI18N
            cleanup(getNameSpaceFolder(namespace));
        } finally {
            ..log(."finnished bugtrackig storage cleanup for {0}"new Object[] {namespace}); // NOI18N
        }
    }
    private void cleanup(File repo) {
        try {
            ..log(."starting bugtrackig storage cleanup for {0}"new Object[] {repo.getAbsoluteFile()}); // NOI18N
            Set<StringlivingIssues = new HashSet<String>();
            File[] queries = repo.listFiles(new FilenameFilter() {
                public boolean accept(File dirString name) {
                    return name.endsWith();
                }
            });
            if(queries != null && queries.length > 0) {
                for (File lq : queries) {
                    FileLock lock = .getLock(lq);
                    List<Stringids;
                    try {
                        synchronized(lock) {
                            ids = readQuery(getDataInputStream(lq));
                        }
                    } finally {
                        if(lock != nulllock.release();
                    }
                    if(ids == null || ids.size() == 0) {
                        continue;
                    }
                    livingIssues.addAll(ids);
                }
            }
            queries = repo.listFiles(new FilenameFilter() {
                public boolean accept(File dirString name) {
                    return name.endsWith();
                }
            });
            if(queries != null) {
                for (File lq : queries) {
                    Map<StringLongids;
                    FileLock lock = .getLock(lq);
                    try {
                        synchronized(lock) {
                            ids = readArchivedQueryIssues(getDataInputStream(lq));
                        }
                    } finally {
                        if(lock != nulllock.release();
                    }
                    if(ids == null || ids.size() == 0) {
                        continue;
                    }
                    livingIssues.addAll(ids.keySet());
                }
            }
            ..log(."living query issues {0}"new Object[] {livingIssues}); // NOI18N
            File[] issues = repo.listFiles(new FilenameFilter() {
                public boolean accept(File dirString name) {
                    return name.endsWith();
                }
            });
            if(issues != null) {
                for (File issue : issues) {
                    String id = issue.getName();
                    id = id.substring(0, id.length() - .length());
                    if(!livingIssues.contains(id)) {
                        ..log(."removing issue {0}"new Object[] {id}); // NOI18N
                        FileLock lock = .getLock(issue);
                        try {
                            synchronized(lock) {
                                issue.delete();
                            }
                        } finally {
                            if(lock != nulllock.release();
                        }
                    }
                }
            }
            
        } catch (IOException ex) {
            ..log(.nullex); // NOI18N
        } catch (InterruptedException ex) {
            ..log(.nullex); // NOI18N
        } finally {
            ..log(."finished bugtrackig storage cleanup for {0}"new Object[] {repo.getAbsoluteFile()}); // NOI18N
        }
    }
    private File getStorageRootFile() {
        String userDir = System.getProperty("netbeans.user");                   // NOI18N
        return new File(new File(userDir"var"), "bugtracking");               // NOI18N
    }
    private void writeStorage() {
        DataOutputStream dos = null;
        try {
            dos = getDataOutputStream(new File(), false);
            writeString(dos);
            dos.flush();
        } catch (IOException e) {
            ..log(.nulle);
        } catch (InterruptedException ie) {
            ..log(.nullie);
        } finally {
            if (dos != null) {
                try { dos.close(); } catch (IOException e) { }
            }
        }
    }
    private void writeString(DataOutputStream dosString strthrows IOException {
        if(str != null) {
            dos.writeInt(str.length());
            dos.writeChars(str);
        } else {
            dos.writeInt(0);
        }
    }
    private static String readString(DataInputStream disthrows IOException {
        int len = dis.readInt();
        if(len == 0) {
            return "";                                                          // NOI18N
        }
        StringBuffer sb = new StringBuffer();                
        while(len-- > 0) {
            char c = dis.readChar();
            sb.append(c);                       
        }        
        return sb.toString();
    }
        ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(getFileOutputStream(issueFilefalse)));
        ZipEntry entry = new ZipEntry(issueFile.getName());
        zos.putNextEntry(entry);
        return new DataOutputStream(zos);
    }
        if(!file.exists()) return null;
        ZipInputStream zis = new ZipInputStream(new BufferedInputStream(getFileInputStream(file)));
        zis.getNextEntry();
        return new DataInputStream(zis);
    }
    private File getIssueFile(File folderString id) {
        return new File(folderid + );
    }
    private DataOutputStream getDataOutputStream(File fileboolean appendthrows IOExceptionInterruptedException {
        return new DataOutputStream(getFileOutputStream(fileappend));
    }
        return new DataInputStream(getFileInputStream(file));
    }
    private FileOutputStream getFileOutputStream(File fileboolean appendthrows IOExceptionInterruptedException {
        int retry = 0;
        while (true) {
            try {
                return new FileOutputStream(fileappend);
            } catch (IOException ioex) {
                retry++;
                if (retry > 7) {
                    throw ioex;
                }
                Thread.sleep(retry * 30);
            }
        }
    }
        int retry = 0;
        while (true) {
            try {
                return new FileInputStream(file);
            } catch (IOException ioex) {
                retry++;
                if (retry > 7) {
                    throw ioex;
                }
                Thread.sleep(retry * 30);
            }
        }
    }
    private static void copyStreams(OutputStream outInputStream inthrows IOException {
        byte [] buffer = new byte[4096];
        for (;;) {
            int n = in.read(buffer);
            if (n < 0) break;
            out.write(buffer, 0, n);
        }
    }
    private File getNameSpaceFolder(String url) {
        File folder = new File(, TextUtils.encodeURL(url));
        if(!folder.exists()) {
            folder.mkdirs();
        }
        return folder;
    }
        return getDataOutputStream(queryFilefalse);
    }
    private DataInputStream getQueryInputStream(File queryFilethrows IOExceptionInterruptedException {
        if(!queryFile.exists()) return null;
        return getDataInputStream(queryFile);
    }
    private File getQueryFile(File folderString queryNameboolean archived){
        return new File(folder, TextUtils.encodeURL(queryName) + (archived ?  : ));
    }
    private class FileLocks {
        private final Map<StringFileLocklocks = new HashMap<StringFileLock>();
        FileLock getLock(File file) {
            synchronized() {
                FileLock fl = .get(file.getAbsolutePath());
                if(fl == null) {
                    fl = new FileLock(file);
                }
                .put(file.getAbsolutePath(), fl);
                return fl;
            }
        }
    }
    class FileLock {
        private final File file;
        public FileLock(File file) {
            this. = file;
        }
        void release() {
            synchronized(.) {
                ..remove(.getAbsolutePath());
            }
        }
    }
    
New to GrepCode? Check out our FAQ X