All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Search JAR files by class name

Source code of the class AbstractIndexedFileCacheBacking.java part of aspectjweaver version 1.8.9

Go to download Show more of this group Show artifacts with the name aspectjweaver
        /*******************************************************************************
 * Copyright (c) 2012 Contributors.
 * All rights reserved.
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution and is available at
 * http://eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   John Kew (vmware)         	initial implementation
 *   Lyor Goldstein (vmware)	add support for weaved class being re-defined
 *******************************************************************************/
package org.aspectj.weaver.tools.cache;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Map;
import java.util.TreeMap;

import org.aspectj.util.LangUtil;

/**
 * Uses an index file to keep track of the cached entries
 */
public abstract class AbstractIndexedFileCacheBacking extends AbstractFileCacheBacking {
	/**
	 * Default name of cache index file - assumed to contain {@link IndexEntry}-s
	 */
	public static final String INDEX_FILE = "cache.idx";
	protected static final IndexEntry[]	EMPTY_INDEX=new IndexEntry[0];
	protected static final String[]	EMPTY_KEYS=new String[0];

	private final File	indexFile;

	protected AbstractIndexedFileCacheBacking(File cacheDir) {
		super(cacheDir);

        indexFile = new File(cacheDir, INDEX_FILE);
	}

    public File getIndexFile () {
        return indexFile;
    }

    public String[] getKeys(String regex) {
    	Map	index=getIndex();
    	if ((index == null) || index.isEmpty()) {
    		return EMPTY_KEYS;
    	}

        Collection  matches=new LinkedList();
        synchronized(index) {
            for (String key : index.keySet()) {
                if (key.matches(regex)) {
                    matches.add(key);
                }
            }
        }

        if (matches.isEmpty()) {
            return EMPTY_KEYS;
        } else {
            return matches.toArray(new String[matches.size()]);
        }
    }

    protected Map readIndex () {
    	return readIndex(getCacheDirectory(), getIndexFile());
    }

    protected void writeIndex () {
    	writeIndex(getIndexFile());
    }

    protected void writeIndex (File file) {
    	try {
    		writeIndex(file, getIndex());
    	} catch(Exception e) {
    		if ((logger != null) && logger.isTraceEnabled()) {
    			logger.warn("writeIndex(" + file + ") " + e.getClass().getSimpleName() + ": " + e.getMessage(), e);
    		}
    	}
    }

    protected abstract Map getIndex ();

    protected Map readIndex (File cacheDir, File cacheFile) {
        Map indexMap=new TreeMap();
        IndexEntry[]            idxValues=readIndex(cacheFile);
        if (LangUtil.isEmpty(idxValues)) {
        	if ((logger != null) && logger.isTraceEnabled()) {
                logger.debug("readIndex(" + cacheFile + ") no index entries");
        	}
        	return indexMap;
        }

        for (IndexEntry ie : idxValues) {
            IndexEntry  resEntry=resolveIndexMapEntry(cacheDir, ie);
            if (resEntry != null) {
                indexMap.put(resEntry.key, resEntry);
            } else if ((logger != null) && logger.isTraceEnabled()) {
                logger.debug("readIndex(" + cacheFile + ") skip " + ie.key);
            }
        }

        return indexMap;
    }

    protected IndexEntry resolveIndexMapEntry (File cacheDir, IndexEntry ie) {
    	return ie;
    }

	public IndexEntry[] readIndex(File indexFile) {
		if (!indexFile.canRead()) {
			return EMPTY_INDEX;
		}

		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream(indexFile));
			return (IndexEntry[]) ois.readObject();
		} catch (Exception e) {
			if ((logger != null) && logger.isTraceEnabled()) {
				logger.error("Failed (" + e.getClass().getSimpleName() + ")"
						   + " to read index from " + indexFile.getAbsolutePath()
						   + " : " + e.getMessage(), e);
			}
			delete(indexFile);
		} finally {
			close(ois, indexFile);
		}

		return EMPTY_INDEX;
	}

	protected void writeIndex (File indexFile, Map index) throws IOException {
		writeIndex(indexFile, LangUtil.isEmpty(index) ? Collections.emptyList() : index.values());
	}

    protected void writeIndex (File indexFile, IndexEntry ... entries) throws IOException {
        writeIndex(indexFile, LangUtil.isEmpty(entries) ? Collections.emptyList() : Arrays.asList(entries));
    }

    protected void writeIndex (File indexFile, Collection entries) throws IOException {
        File    indexDir=indexFile.getParentFile();
        if ((!indexDir.exists()) && (!indexDir.mkdirs())) {
            throw new IOException("Failed to create path to " + indexFile.getAbsolutePath());
        }

        int             numEntries=LangUtil.isEmpty(entries) ? 0 : entries.size();
        IndexEntry[]    entryValues=(numEntries <= 0) ? null : entries.toArray(new IndexEntry[numEntries]);
        // if no entries, simply delete the index file
        if (LangUtil.isEmpty(entryValues)) {
            if (indexFile.exists() && (!indexFile.delete())) {
                throw new StreamCorruptedException("Failed to clean up index file at " + indexFile.getAbsolutePath());
            }

            return;
        }

        ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(indexFile), 4096));
        try {
            oos.writeObject(entryValues);
        } finally {
            close(oos, indexFile);
        }
    }

    public static final IndexEntry createIndexEntry (CachedClassEntry classEntry, byte[] originalBytes) {
        if (classEntry == null) {
            return null;
        }

        IndexEntry  indexEntry = new IndexEntry();
        indexEntry.key = classEntry.getKey();
        indexEntry.generated = classEntry.isGenerated();
        indexEntry.ignored = classEntry.isIgnored();
    	indexEntry.crcClass = crc(originalBytes);
        if (!classEntry.isIgnored()) {
            indexEntry.crcWeaved = crc(classEntry.getBytes());
        }

        return indexEntry;
    }

	/**
	 * The default index entry in the index file 
	 */
	public static class IndexEntry implements Serializable, Cloneable {
		private static final long serialVersionUID = 756391290557029363L;

		public String key;
		public boolean generated;
		public boolean ignored;
		public long crcClass;
		public long crcWeaved;
		
		public IndexEntry () {
			super();
		}

		@Override
		public IndexEntry clone () {
			try {
				return getClass().cast(super.clone());
			} catch(CloneNotSupportedException e) {
				throw new RuntimeException("Failed to clone: " + toString() + ": " + e.getMessage(), e);
			}
		}

		@Override
		public int hashCode() {
			return (int) (key.hashCode()
				 + (generated ? 1 : 0)
				 + (ignored ? 1 : 0)
				 + crcClass
				 + crcWeaved);
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null)
				return false;
			if (this == obj)
				return true;
			if (getClass() != obj.getClass())
				return false;

			IndexEntry	other=(IndexEntry) obj;
			if (this.key.equals(other.key)
			 && (this.ignored == other.ignored)
			 && (this.generated == other.generated)
			 && (this.crcClass == other.crcClass)
			 && (this.crcWeaved == other.crcWeaved)) {
				return true;
			} else {
				return false;
			}
		}

		@Override
		public String toString() {
			return key
				 + "[" + (generated ? "generated" : "ignored") + "]"
				 + ";crcClass=0x" + Long.toHexString(crcClass)
				 + ";crcWeaved=0x" + Long.toHexString(crcWeaved)
				 ;
		}
	}

}




© 2018 Weber Informatics LLC