freemarker

16:35:56.416 INFO  jd.cli.Main - Decompiling freemarker.jar
package freemarker.cache;

public abstract interface CacheStorage
{
  public abstract Object get(Object paramObject);
  
  public abstract void put(Object paramObject1, Object paramObject2);
  
  public abstract void remove(Object paramObject);
  
  public abstract void clear();
}

/* Location:
 * Qualified Name:     freemarker.cache.CacheStorage
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.net.URL;

public class ClassTemplateLoader
  extends URLTemplateLoader
{
  private Class loaderClass;
  private String path;
  
  /**
   * @deprecated
   */
  public ClassTemplateLoader()
  {
    setFields(getClass(), "/");
  }
  
  /**
   * @deprecated
   */
  public ClassTemplateLoader(Class loaderClass)
  {
    setFields(loaderClass, "");
  }
  
  public ClassTemplateLoader(Class loaderClass, String path)
  {
    setFields(loaderClass, path);
  }
  
  protected URL getURL(String name)
  {
    return loaderClass.getResource(path + name);
  }
  
  private void setFields(Class loaderClass, String path)
  {
    if (loaderClass == null) {
      throw new IllegalArgumentException("loaderClass == null");
    }
    if (path == null) {
      throw new IllegalArgumentException("path == null");
    }
    this.loaderClass = loaderClass;
    this.path = canonicalizePrefix(path);
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.ClassTemplateLoader
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

public abstract interface ConcurrentCacheStorage
  extends CacheStorage
{
  public abstract boolean isConcurrent();
}

/* Location:
 * Qualified Name:     freemarker.cache.ConcurrentCacheStorage
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import freemarker.template.utility.ClassUtil;
import freemarker.template.utility.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.Map;

class ConcurrentMapFactory
{
  private static final Class mapClass = ;
  private static final Class hashMapClass = getHashMapClass();
  
  static Map createMap()
  {
    try
    {
      return (Map)hashMapClass.newInstance();
    }
    catch (Exception e)
    {
      throw new UndeclaredThrowableException(e);
    }
  }
  
  static boolean isConcurrent(Map map)
  {
    return (mapClass != null) && (mapClass.isInstance(map));
  }
  
  private static Class getMapClass()
  {
    try
    {
      return ClassUtil.forName("java.util.concurrent.ConcurrentMap");
    }
    catch (ClassNotFoundException e) {}
    return null;
  }
  
  private static Class getHashMapClass()
  {
    try
    {
      return ClassUtil.forName("java.util.concurrent.ConcurrentHashMap");
    }
    catch (ClassNotFoundException e) {}
    return HashMap.class;
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.ConcurrentMapFactory
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.PrivilegedExceptionAction;

class FileTemplateLoader$1
  implements PrivilegedExceptionAction
{
  private final File val$baseDir;
  private final boolean val$allowLinking;
  private final FileTemplateLoader this$0;
  
  FileTemplateLoader$1(FileTemplateLoader paramFileTemplateLoader, File paramFile, boolean paramBoolean)
  {
    this$0 = paramFileTemplateLoader;val$baseDir = paramFile;val$allowLinking = paramBoolean;
  }
  
  public Object run()
    throws IOException
  {
    if (!val$baseDir.exists()) {
      throw new FileNotFoundException(val$baseDir + " does not exist.");
    }
    if (!val$baseDir.isDirectory()) {
      throw new IOException(val$baseDir + " is not a directory.");
    }
    Object[] retval = new Object[2];
    if (val$allowLinking)
    {
      retval[0] = val$baseDir;
      retval[1] = null;
    }
    else
    {
      retval[0] = val$baseDir.getCanonicalFile();
      String basePath = ((File)retval[0]).getPath();
      if (!basePath.endsWith(File.separator)) {
        basePath = basePath + File.separatorChar;
      }
      retval[1] = basePath;
    }
    return retval;
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.FileTemplateLoader.1
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.File;
import java.io.IOException;
import java.security.PrivilegedExceptionAction;

class FileTemplateLoader$2
  implements PrivilegedExceptionAction
{
  private final String val$name;
  private final FileTemplateLoader this$0;
  
  FileTemplateLoader$2(FileTemplateLoader paramFileTemplateLoader, String paramString)
  {
    this$0 = paramFileTemplateLoader;val$name = paramString;
  }
  
  public Object run()
    throws IOException
  {
    File source = new File(this$0.baseDir, FileTemplateLoader.access$000() ? val$name : val$name.replace('/', File.separatorChar));
    if (!source.isFile()) {
      return null;
    }
    if (FileTemplateLoader.access$100(this$0) != null)
    {
      String normalized = source.getCanonicalPath();
      if (!normalized.startsWith(FileTemplateLoader.access$100(this$0))) {
        throw new SecurityException(source.getAbsolutePath() + " resolves to " + normalized + " which " + " doesn't start with " + FileTemplateLoader.access$100(this$0));
      }
    }
    return source;
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.FileTemplateLoader.2
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.File;
import java.security.PrivilegedAction;

class FileTemplateLoader$3
  implements PrivilegedAction
{
  private final Object val$templateSource;
  private final FileTemplateLoader this$0;
  
  FileTemplateLoader$3(FileTemplateLoader paramFileTemplateLoader, Object paramObject)
  {
    this$0 = paramFileTemplateLoader;val$templateSource = paramObject;
  }
  
  public Object run()
  {
    return new Long(((File)val$templateSource).lastModified());
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.FileTemplateLoader.3
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.PrivilegedExceptionAction;

class FileTemplateLoader$4
  implements PrivilegedExceptionAction
{
  private final Object val$templateSource;
  private final String val$encoding;
  private final FileTemplateLoader this$0;
  
  FileTemplateLoader$4(FileTemplateLoader paramFileTemplateLoader, Object paramObject, String paramString)
  {
    this$0 = paramFileTemplateLoader;val$templateSource = paramObject;val$encoding = paramString;
  }
  
  public Object run()
    throws IOException
  {
    if (!(val$templateSource instanceof File)) {
      throw new IllegalArgumentException("templateSource is a: " + val$templateSource.getClass().getName());
    }
    return new InputStreamReader(new FileInputStream((File)val$templateSource), val$encoding);
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.FileTemplateLoader.4
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import freemarker.template.utility.SecurityUtilities;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

public class FileTemplateLoader
  implements TemplateLoader
{
  private static final boolean SEP_IS_SLASH = File.separatorChar == '/';
  public final File baseDir;
  private final String canonicalPath;
  
  public FileTemplateLoader()
    throws IOException
  {
    this(new File(SecurityUtilities.getSystemProperty("user.dir")));
  }
  
  public FileTemplateLoader(File baseDir)
    throws IOException
  {
    this(baseDir, false);
  }
  
  public FileTemplateLoader(File baseDir, boolean allowLinking)
    throws IOException
  {
    try
    {
      Object[] retval = (Object[])AccessController.doPrivileged(new PrivilegedExceptionAction()
      {
        private final File val$baseDir;
        private final boolean val$allowLinking;
        
        public Object run()
          throws IOException
        {
          if (!val$baseDir.exists()) {
            throw new FileNotFoundException(val$baseDir + " does not exist.");
          }
          if (!val$baseDir.isDirectory()) {
            throw new IOException(val$baseDir + " is not a directory.");
          }
          Object[] retval = new Object[2];
          if (val$allowLinking)
          {
            retval[0] = val$baseDir;
            retval[1] = null;
          }
          else
          {
            retval[0] = val$baseDir.getCanonicalFile();
            String basePath = ((File)retval[0]).getPath();
            if (!basePath.endsWith(File.separator)) {
              basePath = basePath + File.separatorChar;
            }
            retval[1] = basePath;
          }
          return retval;
        }
      });
      this.baseDir = ((File)retval[0]);
      canonicalPath = ((String)retval[1]);
    }
    catch (PrivilegedActionException e)
    {
      throw ((IOException)e.getException());
    }
  }
  
  public Object findTemplateSource(String name)
    throws IOException
  {
    try
    {
      AccessController.doPrivileged(new PrivilegedExceptionAction()
      {
        private final String val$name;
        
        public Object run()
          throws IOException
        {
          File source = new File(baseDir, FileTemplateLoader.SEP_IS_SLASH ? val$name : val$name.replace('/', File.separatorChar));
          if (!source.isFile()) {
            return null;
          }
          if (canonicalPath != null)
          {
            String normalized = source.getCanonicalPath();
            if (!normalized.startsWith(canonicalPath)) {
              throw new SecurityException(source.getAbsolutePath() + " resolves to " + normalized + " which " + " doesn't start with " + canonicalPath);
            }
          }
          return source;
        }
      });
    }
    catch (PrivilegedActionException e)
    {
      throw ((IOException)e.getException());
    }
  }
  
  public long getLastModified(Object templateSource)
  {
    ((Long)AccessController.doPrivileged(new PrivilegedAction()
    {
      private final Object val$templateSource;
      
      public Object run()
      {
        return new Long(((File)val$templateSource).lastModified());
      }
    })).longValue();
  }
  
  public Reader getReader(Object templateSource, String encoding)
    throws IOException
  {
    try
    {
      (Reader)AccessController.doPrivileged(new PrivilegedExceptionAction()
      {
        private final Object val$templateSource;
        private final String val$encoding;
        
        public Object run()
          throws IOException
        {
          if (!(val$templateSource instanceof File)) {
            throw new IllegalArgumentException("templateSource is a: " + val$templateSource.getClass().getName());
          }
          return new InputStreamReader(new FileInputStream((File)val$templateSource), val$encoding);
        }
      });
    }
    catch (PrivilegedActionException e)
    {
      throw ((IOException)e.getException());
    }
  }
  
  public void closeTemplateSource(Object templateSource) {}
}

/* Location:
 * Qualified Name:     freemarker.cache.FileTemplateLoader
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

final class MruCacheStorage$MruEntry
{
  private MruEntry prev;
  private MruEntry next;
  private final Object key;
  private Object value;
  
  MruCacheStorage$MruEntry()
  {
    makeHead();
    key = (value = null);
  }
  
  MruCacheStorage$MruEntry(Object key, Object value)
  {
    this.key = key;
    this.value = value;
  }
  
  Object getKey()
  {
    return key;
  }
  
  Object getValue()
  {
    return value;
  }
  
  void setValue(Object value)
  {
    this.value = value;
  }
  
  MruEntry getPrevious()
  {
    return prev;
  }
  
  void linkAfter(MruEntry entry)
  {
    next = next;
    next = this;
    prev = entry;
    next.prev = this;
  }
  
  void unlink()
  {
    next.prev = prev;
    prev.next = next;
    prev = null;
    next = null;
  }
  
  void makeHead()
  {
    next = this;prev = this;
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.MruCacheStorage.MruEntry
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;

class MruCacheStorage$MruReference
  extends SoftReference
{
  private final Object key;
  
  MruCacheStorage$MruReference(MruCacheStorage.MruEntry entry, ReferenceQueue queue)
  {
    super(entry.getValue(), queue);
    key = entry.getKey();
  }
  
  Object getKey()
  {
    return key;
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.MruCacheStorage.MruReference
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;

public class MruCacheStorage
  implements CacheStorage
{
  private final MruEntry strongHead = new MruEntry();
  private final MruEntry softHead = new MruEntry();
  private final Map map;
  private final ReferenceQueue refQueue;
  private final int maxStrongSize;
  private final int maxSoftSize;
  private int strongSize;
  private int softSize;
  
  public MruCacheStorage(int maxStrongSize, int maxSoftSize)
  {
    softHead.linkAfter(strongHead);
    
    map = new HashMap();
    refQueue = new ReferenceQueue();
    
    strongSize = 0;
    softSize = 0;
    if (maxStrongSize < 0) {
      throw new IllegalArgumentException("maxStrongSize < 0");
    }
    if (maxSoftSize < 0) {
      throw new IllegalArgumentException("maxSoftSize < 0");
    }
    this.maxStrongSize = maxStrongSize;
    this.maxSoftSize = maxSoftSize;
  }
  
  public Object get(Object key)
  {
    removeClearedReferences();
    MruEntry entry = (MruEntry)map.get(key);
    if (entry == null) {
      return null;
    }
    relinkEntryAfterStrongHead(entry, null);
    Object value = entry.getValue();
    if ((value instanceof MruReference)) {
      return ((MruReference)value).get();
    }
    return value;
  }
  
  public void put(Object key, Object value)
  {
    removeClearedReferences();
    MruEntry entry = (MruEntry)map.get(key);
    if (entry == null)
    {
      entry = new MruEntry(key, value);
      map.put(key, entry);
      linkAfterStrongHead(entry);
    }
    else
    {
      relinkEntryAfterStrongHead(entry, value);
    }
  }
  
  public void remove(Object key)
  {
    removeClearedReferences();
    removeInternal(key);
  }
  
  private void removeInternal(Object key)
  {
    MruEntry entry = (MruEntry)map.remove(key);
    if (entry != null) {
      unlinkEntryAndInspectIfSoft(entry);
    }
  }
  
  public void clear()
  {
    strongHead.makeHead();
    softHead.linkAfter(strongHead);
    map.clear();
    strongSize = (softSize = 0);
    while (refQueue.poll() != null) {}
  }
  
  private void relinkEntryAfterStrongHead(MruEntry entry, Object newValue)
  {
    if ((unlinkEntryAndInspectIfSoft(entry)) && (newValue == null))
    {
      MruReference mref = (MruReference)entry.getValue();
      Object strongValue = mref.get();
      if (strongValue != null)
      {
        entry.setValue(strongValue);
        linkAfterStrongHead(entry);
      }
      else
      {
        map.remove(mref.getKey());
      }
    }
    else
    {
      if (newValue != null) {
        entry.setValue(newValue);
      }
      linkAfterStrongHead(entry);
    }
  }
  
  private void linkAfterStrongHead(MruEntry entry)
  {
    entry.linkAfter(strongHead);
    if (strongSize == maxStrongSize)
    {
      MruEntry lruStrong = softHead.getPrevious();
      if (lruStrong != strongHead)
      {
        lruStrong.unlink();
        if (maxSoftSize > 0)
        {
          lruStrong.linkAfter(softHead);
          lruStrong.setValue(new MruReference(lruStrong, refQueue));
          if (softSize == maxSoftSize)
          {
            MruEntry lruSoft = strongHead.getPrevious();
            lruSoft.unlink();
            map.remove(lruSoft.getKey());
          }
          else
          {
            softSize += 1;
          }
        }
        else
        {
          map.remove(lruStrong.getKey());
        }
      }
    }
    else
    {
      strongSize += 1;
    }
  }
  
  private boolean unlinkEntryAndInspectIfSoft(MruEntry entry)
  {
    entry.unlink();
    if ((entry.getValue() instanceof MruReference))
    {
      softSize -= 1;
      return true;
    }
    strongSize -= 1;
    return false;
  }
  
  private void removeClearedReferences()
  {
    for (;;)
    {
      MruReference ref = (MruReference)refQueue.poll();
      if (ref == null) {
        break;
      }
      removeInternal(ref.getKey());
    }
  }
  
  private static final class MruEntry
  {
    private MruEntry prev;
    private MruEntry next;
    private final Object key;
    private Object value;
    
    MruEntry()
    {
      makeHead();
      key = (value = null);
    }
    
    MruEntry(Object key, Object value)
    {
      this.key = key;
      this.value = value;
    }
    
    Object getKey()
    {
      return key;
    }
    
    Object getValue()
    {
      return value;
    }
    
    void setValue(Object value)
    {
      this.value = value;
    }
    
    MruEntry getPrevious()
    {
      return prev;
    }
    
    void linkAfter(MruEntry entry)
    {
      next = next;
      next = this;
      prev = entry;
      next.prev = this;
    }
    
    void unlink()
    {
      next.prev = prev;
      prev.next = next;
      prev = null;
      next = null;
    }
    
    void makeHead()
    {
      next = this;prev = this;
    }
  }
  
  private static class MruReference
    extends SoftReference
  {
    private final Object key;
    
    MruReference(MruCacheStorage.MruEntry entry, ReferenceQueue queue)
    {
      super(queue);
      key = entry.getKey();
    }
    
    Object getKey()
    {
      return key;
    }
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.MruCacheStorage
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.IOException;
import java.io.Reader;

final class MultiTemplateLoader$MultiSource
{
  private final Object source;
  private final TemplateLoader loader;
  
  MultiTemplateLoader$MultiSource(Object source, TemplateLoader loader)
  {
    this.source = source;
    this.loader = loader;
  }
  
  long getLastModified()
  {
    return loader.getLastModified(source);
  }
  
  Reader getReader(String encoding)
    throws IOException
  {
    return loader.getReader(source, encoding);
  }
  
  void close()
    throws IOException
  {
    loader.closeTemplateSource(source);
  }
  
  public boolean equals(Object o)
  {
    if ((o instanceof MultiSource))
    {
      MultiSource m = (MultiSource)o;
      return (loader.equals(loader)) && (source.equals(source));
    }
    return false;
  }
  
  public int hashCode()
  {
    return loader.hashCode() + 31 * source.hashCode();
  }
  
  public String toString()
  {
    return source.toString();
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.MultiTemplateLoader.MultiSource
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.IOException;
import java.io.Reader;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class MultiTemplateLoader
  implements StatefulTemplateLoader
{
  private final TemplateLoader[] loaders;
  private final Map lastLoaderForName = Collections.synchronizedMap(new HashMap());
  
  public MultiTemplateLoader(TemplateLoader[] loaders)
  {
    this.loaders = ((TemplateLoader[])loaders.clone());
  }
  
  public Object findTemplateSource(String name)
    throws IOException
  {
    TemplateLoader lastLoader = (TemplateLoader)lastLoaderForName.get(name);
    if (lastLoader != null)
    {
      Object source = lastLoader.findTemplateSource(name);
      if (source != null) {
        return new MultiSource(source, lastLoader);
      }
    }
    for (int i = 0; i < loaders.length; i++)
    {
      TemplateLoader loader = loaders[i];
      Object source = loader.findTemplateSource(name);
      if (source != null)
      {
        lastLoaderForName.put(name, loader);
        return new MultiSource(source, loader);
      }
    }
    lastLoaderForName.remove(name);
    
    return null;
  }
  
  public long getLastModified(Object templateSource)
  {
    return ((MultiSource)templateSource).getLastModified();
  }
  
  public Reader getReader(Object templateSource, String encoding)
    throws IOException
  {
    return ((MultiSource)templateSource).getReader(encoding);
  }
  
  public void closeTemplateSource(Object templateSource)
    throws IOException
  {
    ((MultiSource)templateSource).close();
  }
  
  public void resetState()
  {
    lastLoaderForName.clear();
    for (int i = 0; i < loaders.length; i++)
    {
      TemplateLoader loader = loaders[i];
      if ((loader instanceof StatefulTemplateLoader)) {
        ((StatefulTemplateLoader)loader).resetState();
      }
    }
  }
  
  private static final class MultiSource
  {
    private final Object source;
    private final TemplateLoader loader;
    
    MultiSource(Object source, TemplateLoader loader)
    {
      this.source = source;
      this.loader = loader;
    }
    
    long getLastModified()
    {
      return loader.getLastModified(source);
    }
    
    Reader getReader(String encoding)
      throws IOException
    {
      return loader.getReader(source, encoding);
    }
    
    void close()
      throws IOException
    {
      loader.closeTemplateSource(source);
    }
    
    public boolean equals(Object o)
    {
      if ((o instanceof MultiSource))
      {
        MultiSource m = (MultiSource)o;
        return (loader.equals(loader)) && (source.equals(source));
      }
      return false;
    }
    
    public int hashCode()
    {
      return loader.hashCode() + 31 * source.hashCode();
    }
    
    public String toString()
    {
      return source.toString();
    }
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.MultiTemplateLoader
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

public class NullCacheStorage
  implements ConcurrentCacheStorage
{
  public boolean isConcurrent()
  {
    return true;
  }
  
  public Object get(Object key)
  {
    return null;
  }
  
  public void put(Object key, Object value) {}
  
  public void remove(Object key) {}
  
  public void clear() {}
}

/* Location:
 * Qualified Name:     freemarker.cache.NullCacheStorage
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;

final class SoftCacheStorage$SoftValueReference
  extends SoftReference
{
  private final Object key;
  
  SoftCacheStorage$SoftValueReference(Object key, Object value, ReferenceQueue queue)
  {
    super(value, queue);
    this.key = key;
  }
  
  Object getKey()
  {
    return key;
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.SoftCacheStorage.SoftValueReference
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import freemarker.template.utility.UndeclaredThrowableException;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class SoftCacheStorage
  implements ConcurrentCacheStorage
{
  private static final Method atomicRemove = ;
  private final ReferenceQueue queue = new ReferenceQueue();
  private final Map map;
  private final boolean concurrent;
  
  public SoftCacheStorage()
  {
    this(ConcurrentMapFactory.createMap());
  }
  
  public boolean isConcurrent()
  {
    return concurrent;
  }
  
  public SoftCacheStorage(Map backingMap)
  {
    map = backingMap;
    concurrent = ConcurrentMapFactory.isConcurrent(map);
  }
  
  public Object get(Object key)
  {
    processQueue();
    Reference ref = (Reference)map.get(key);
    return ref == null ? null : ref.get();
  }
  
  public void put(Object key, Object value)
  {
    processQueue();
    map.put(key, new SoftValueReference(key, value, queue));
  }
  
  public void remove(Object key)
  {
    processQueue();
    map.remove(key);
  }
  
  public void clear()
  {
    map.clear();
    processQueue();
  }
  
  private void processQueue()
  {
    for (;;)
    {
      SoftValueReference ref = (SoftValueReference)queue.poll();
      if (ref == null) {
        return;
      }
      Object key = ref.getKey();
      if (concurrent) {
        try
        {
          atomicRemove.invoke(map, new Object[] { key, ref });
        }
        catch (IllegalAccessException e)
        {
          throw new UndeclaredThrowableException(e);
        }
        catch (InvocationTargetException e)
        {
          throw new UndeclaredThrowableException(e);
        }
      } else if (map.get(key) == ref) {
        map.remove(key);
      }
    }
  }
  
  private static final class SoftValueReference
    extends SoftReference
  {
    private final Object key;
    
    SoftValueReference(Object key, Object value, ReferenceQueue queue)
    {
      super(queue);
      this.key = key;
    }
    
    Object getKey()
    {
      return key;
    }
  }
  
  private static Method getAtomicRemoveMethod()
  {
    try
    {
      return Class.forName("java.util.concurrent.ConcurrentMap").getMethod("remove", new Class[] { Object.class, Object.class });
    }
    catch (ClassNotFoundException e)
    {
      return null;
    }
    catch (NoSuchMethodException e)
    {
      throw new UndeclaredThrowableException(e);
    }
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.SoftCacheStorage
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

public abstract interface StatefulTemplateLoader
  extends TemplateLoader
{
  public abstract void resetState();
}

/* Location:
 * Qualified Name:     freemarker.cache.StatefulTemplateLoader
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

class StringTemplateLoader$StringTemplateSource
{
  private final String name;
  private final String source;
  private final long lastModified;
  
  StringTemplateLoader$StringTemplateSource(String name, String source, long lastModified)
  {
    if (name == null) {
      throw new IllegalArgumentException("name == null");
    }
    if (source == null) {
      throw new IllegalArgumentException("source == null");
    }
    if (lastModified < -1L) {
      throw new IllegalArgumentException("lastModified < -1L");
    }
    this.name = name;
    this.source = source;
    this.lastModified = lastModified;
  }
  
  public boolean equals(Object obj)
  {
    if ((obj instanceof StringTemplateSource)) {
      return name.equals(name);
    }
    return false;
  }
  
  public int hashCode()
  {
    return name.hashCode();
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.StringTemplateLoader.StringTemplateSource
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

public class StringTemplateLoader
  implements TemplateLoader
{
  private final Map templates;
  
  public StringTemplateLoader()
  {
    templates = new HashMap();
  }
  
  public void putTemplate(String name, String templateSource)
  {
    putTemplate(name, templateSource, System.currentTimeMillis());
  }
  
  public void putTemplate(String name, String templateSource, long lastModified)
  {
    templates.put(name, new StringTemplateSource(name, templateSource, lastModified));
  }
  
  public void closeTemplateSource(Object templateSource) {}
  
  public Object findTemplateSource(String name)
  {
    return templates.get(name);
  }
  
  public long getLastModified(Object templateSource)
  {
    return lastModified;
  }
  
  public Reader getReader(Object templateSource, String encoding)
  {
    return new StringReader(source);
  }
  
  private static class StringTemplateSource
  {
    private final String name;
    private final String source;
    private final long lastModified;
    
    StringTemplateSource(String name, String source, long lastModified)
    {
      if (name == null) {
        throw new IllegalArgumentException("name == null");
      }
      if (source == null) {
        throw new IllegalArgumentException("source == null");
      }
      if (lastModified < -1L) {
        throw new IllegalArgumentException("lastModified < -1L");
      }
      this.name = name;
      this.source = source;
      this.lastModified = lastModified;
    }
    
    public boolean equals(Object obj)
    {
      if ((obj instanceof StringTemplateSource)) {
        return name.equals(name);
      }
      return false;
    }
    
    public int hashCode()
    {
      return name.hashCode();
    }
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.StringTemplateLoader
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.util.Map;

public class StrongCacheStorage
  implements ConcurrentCacheStorage
{
  private final Map map = ConcurrentMapFactory.createMap();
  
  public boolean isConcurrent()
  {
    return ConcurrentMapFactory.isConcurrent(map);
  }
  
  public Object get(Object key)
  {
    return map.get(key);
  }
  
  public void put(Object key, Object value)
  {
    map.put(key, value);
  }
  
  public void remove(Object key)
  {
    map.remove(key);
  }
  
  public void clear()
  {
    map.clear();
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.StrongCacheStorage
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

class TemplateCache$1 {}

/* Location:
 * Qualified Name:     freemarker.cache.TemplateCache.1
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import freemarker.template.utility.UndeclaredThrowableException;
import java.io.Serializable;

final class TemplateCache$CachedTemplate
  implements Cloneable, Serializable
{
  private static final long serialVersionUID = 1L;
  Object templateOrException;
  Object source;
  long lastChecked;
  long lastModified;
  
  TemplateCache$CachedTemplate(TemplateCache.1 x0)
  {
    this();
  }
  
  public CachedTemplate cloneCachedTemplate()
  {
    try
    {
      return (CachedTemplate)super.clone();
    }
    catch (CloneNotSupportedException e)
    {
      throw new UndeclaredThrowableException(e);
    }
  }
  
  private TemplateCache$CachedTemplate() {}
}

/* Location:
 * Qualified Name:     freemarker.cache.TemplateCache.CachedTemplate
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import java.util.Locale;

final class TemplateCache$TemplateKey
{
  private final String name;
  private final Locale locale;
  private final String encoding;
  private final boolean parse;
  
  TemplateCache$TemplateKey(String name, Locale locale, String encoding, boolean parse)
  {
    this.name = name;
    this.locale = locale;
    this.encoding = encoding;
    this.parse = parse;
  }
  
  public boolean equals(Object o)
  {
    if ((o instanceof TemplateKey))
    {
      TemplateKey tk = (TemplateKey)o;
      return (parse == parse) && (name.equals(name)) && (locale.equals(locale)) && (encoding.equals(encoding));
    }
    return false;
  }
  
  public int hashCode()
  {
    return name.hashCode() ^ locale.hashCode() ^ encoding.hashCode() ^ (parse ? Boolean.FALSE : Boolean.TRUE).hashCode();
  }
}

/* Location:
 * Qualified Name:     freemarker.cache.TemplateCache.TemplateKey
 * Java Class Version: 1.2 (46.0)
 * JD-Core Version:    0.7.1
 */
package freemarker.cache;

import freemarker.core.Environment;
import freemarker.log.Logger;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Template.WrongEncodingException;
import freemarker.template.utility.StringUtil;
import freemarker.template.utility.UndeclaredThrowableException;
import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

public class TemplateCache
{
  private static final String ASTERISKSTR = "*";
  private static final String LOCALE_SEPARATOR = "_";
  private static final char ASTERISK = '*';
  private static final String CURRENT_DIR_PATH_PREFIX = "./";
  private static final String CURRENT_DIR_PATH = "/./";
  private static final String PARENT_DIR_PATH_PREFIX = "../";
  private static final String PARENT_DIR_PATH = "/../";
  private static final char SLASH = '/';
  private static final Logger logger = Logger.getLogger("freemarker.cache");
  private final TemplateLoader mainLoader;
  private final CacheStorage storage;
  private final boolean isStorageConcurrent;
  private long delay = 5000L;
  private boolean localizedLookup = true;
  private Configuration config;
  
  public TemplateCache()
  {
    this(createDefaultTemplateLoader());
  }
  
  private static TemplateLoader createDefaultTemplateLoader()
  {
    try
    {
      return new FileTemplateLoader();
    }
    catch (Exception e)
    {
      logger.warn("Could not create a file template loader for current directory", e);
    }
    return null;
  }
  
  public TemplateCache(TemplateLoader loader)
  {
    this(loader, new SoftCacheStorage());
  }
  
  public TemplateCache(TemplateLoader loader, CacheStorage storage)
  {
    mainLoader = loader;
    this.storage = storage;
    if (storage == null) {
      throw new IllegalArgumentException("storage == null");
    }
    isStorageConcurrent = (((storage instanceof ConcurrentCacheStorage)) && (((ConcurrentCacheStorage)storage).isConcurrent()));
  }
  
  public void setConfiguration(Configuration config)
  {
    this.config = config;
    clear();
  }
  
  public TemplateLoader getTemplateLoader()
  {
    return mainLoader;
  }
  
  public CacheStorage getCacheStorage()
  {
    return storage;
  }
  
  public Template getTemplate(String name, Locale locale, String encoding, boolean parse)
    throws IOException
  {
    if (name == null) {
      throw new IllegalArgumentException("Argument \"name\" can't be null");
    }
    if (locale == null) {
      throw new IllegalArgumentException("Argument \"locale\" can't be null");
    }
    if (encoding == null) {
      throw new IllegalArgumentException("Argument \"encoding\" can't be null");
    }
    name = normalizeName(name);
    if (name == null) {
      return null;
    }
    Template result = null;
    if (mainLoader != null) {
      result = getTemplate(mainLoader, name, locale, encoding, parse);
    }
    return result;
  }
  
  private Template getTemplate(TemplateLoader loader, String name, Locale locale, String encoding, boolean parse)
    throws IOException
  {
    boolean debug = logger.isDebugEnabled();
    String debugName = debug ? StringUtil.jQuoteNoXSS(name) + "[" + StringUtil.jQuoteNoXSS(locale) + "," + encoding + (parse ? ",parsed] " : ",unparsed] ") : null;
    
    TemplateKey tk = new TemplateKey(name, locale, encoding, parse);
    CachedTemplate cachedTemplate;
    CachedTemplate cachedTemplate;
    if (isStorageConcurrent) {
      cachedTemplate = (CachedTemplate)storage.get(tk);
    } else {
      synchronized (storage)
      {
        cachedTemplate = (CachedTemplate)storage.get(tk);
      }
    }
    long now = System.currentTimeMillis();
    long lastModified = -1L;
    Object newlyFoundSource = null;
    boolean rethrown = false;
    try
    {
      boolean lastModifiedNotChanged;
      Template localTemplate2;
      if (cachedTemplate != null)
      {
        Object t;
        if (now - lastChecked < delay)
        {
          if (debug) {
            logger.debug(debugName + "cached copy not yet stale; using cached.");
          }
          t = templateOrException;
          if (((t instanceof Template)) || (t == null)) {
            return (Template)t;
          }
          if ((t instanceof RuntimeException))
          {
            throwLoadFailedException((RuntimeException)t);
          }
          else if ((t instanceof IOException))
          {
            rethrown = true;
            throwLoadFailedException((IOException)t);
          }
          throw new RuntimeException("t is " + t.getClass().getName());
        }
        cachedTemplate = cachedTemplate.cloneCachedTemplate();
        
        lastChecked = now;
        
        newlyFoundSource = findTemplateSource(name, locale);
        if (newlyFoundSource == null)
        {
          if (debug) {
            logger.debug(debugName + "no source found.");
          }
          storeNegativeLookup(tk, cachedTemplate, null);
          return null;
        }
        lastModified = loader.getLastModified(newlyFoundSource);
        lastModifiedNotChanged = lastModified == lastModified;
        boolean sourceEquals = newlyFoundSource.equals(source);
        if ((lastModifiedNotChanged) && (sourceEquals))
        {
          if (debug) {
            logger.debug(debugName + "using cached since " + newlyFoundSource + " didn't change.");
          }
          storeCached(tk, cachedTemplate);
          return (Template)templateOrException;
        }
        if ((debug) && (!sourceEquals)) {
          logger.debug("Updating source, info for cause: sourceEquals=" + sourceEquals + ", newlyFoundSource=" + StringUtil.jQuoteNoXSS(newlyFoundSource) + ", cachedTemplate.source=" + StringUtil.jQuoteNoXSS(source));
        }
        if ((debug) && (!lastModifiedNotChanged)) {
          logger.debug("Updating source, info for cause: lastModifiedNotChanged=" + lastModifiedNotChanged + ", cache lastModified=" + lastModified + " != file lastModified=" + lastModified);
        }
        source = newlyFoundSource;
      }
      else
      {
        if (debug) {
          logger.debug("Could not find template in cache, creating new one; id=[" + StringUtil.jQuoteNoXSS(name) + "[" + StringUtil.jQuoteNoXSS(locale) + "," + encoding + (parse ? ",parsed] " : ",unparsed] ") + "]");
        }
        cachedTemplate = new CachedTemplate(null);
        lastChecked = now;
        newlyFoundSource = findTemplateSource(name, locale);
        if (newlyFoundSource == null)
        {
          storeNegativeLookup(tk, cachedTemplate, null);
          return null;
        }
        source = newlyFoundSource;
        lastModified = (lastModified = Long.MIN_VALUE);
      }
      if (debug) {
        logger.debug("Compiling FreeMarker template " + debugName + " from " + StringUtil.jQuoteNoXSS(newlyFoundSource));
      }
      Object source = source;
      Template t = loadTemplate(loader, name, locale, encoding, parse, source);
      templateOrException = t;
      lastModified = (lastModified == Long.MIN_VALUE ? loader.getLastModified(source) : lastModified);
      
      storeCached(tk, cachedTemplate);
      return t;
    }
    catch (RuntimeException e)
    {
      storeNegativeLookup(tk, cachedTemplate, e);
      throw e;
    }
    catch (IOExc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2017. Infinite Loop Ltd