Coverage Report - org.webslinger.container.FileInfo
 
Classes in this File Line Coverage Branch Coverage Complexity
FileInfo
52%
15/29
0%
0/1
0
FileInfo$Creator
N/A
N/A
0
FileInfo$FileCache
92%
22/24
100%
8/8
0
FileInfo$FileCache$1
50%
1/2
N/A
0
FileInfo$FileInfoVFSDelegate
56%
5/9
N/A
0
FileInfo$FreezableItemKey
0%
0/7
N/A
0
FileInfo$ItemKey
0%
0/9
0%
0/2
0
FileInfo$ReadObjectCreator
0%
0/7
0%
0/1
0
FileInfo$SplitAttributeTTLObject
91%
10/11
100%
2/2
0
 
 1  
 package org.webslinger.container;
 2  
 
 3  
 import java.io.InputStream;
 4  
 import java.io.IOException;
 5  
 import java.util.HashMap;
 6  
 import java.util.Map;
 7  
 import java.util.concurrent.ConcurrentHashMap;
 8  
 import java.util.concurrent.atomic.AtomicReference;
 9  
 import javax.servlet.ServletException;
 10  
 
 11  
 import org.apache.commons.vfs.FileObject;
 12  
 import org.apache.commons.vfs.FileType;
 13  
 
 14  
 import static org.webslinger.lang.ClassUtil.NULL;
 15  
 import org.webslinger.WebslingerInvoker;
 16  
 import org.webslinger.WebslingerServletContext;
 17  
 import org.webslinger.io.IOUtil;
 18  
 import org.webslinger.lang.ConcurrentFreezableCache;
 19  
 import org.webslinger.lang.Freezable;
 20  
 import static org.webslinger.lang.ObjectUtil.equalsHelper;
 21  
 import static org.webslinger.lang.ObjectUtil.hashCodeHelper;
 22  
 import org.webslinger.util.TTLCachedObject;
 23  
 import org.webslinger.util.TTLObject;
 24  
 import org.webslinger.vfs.VFSDelegate;
 25  
 import org.webslinger.vfs.VFSDelegateProxy;
 26  
 
 27  493
 public abstract class FileInfo extends TTLCachedObject<FileInfo.FileCache> {
 28  
     static {
 29  1
         TTLObject.setDefaultTTLForClass(SplitAttributeTTLObject.class, 1000);
 30  1
     }
 31  
 
 32  
     private final WebslingerContainer container;
 33  
 
 34  
     protected final FileObject servletFile;
 35  
     protected String type;
 36  
 
 37  890
     protected FileInfo(WebslingerContainer container, FileObject servletFile) {
 38  890
         this.container = container;
 39  890
         this.servletFile = servletFile;
 40  890
     }
 41  
 
 42  
     protected FileCache getInitial() throws IOException {
 43  493
         return createFileCache(null);
 44  
     }
 45  
 
 46  
     protected FileCache createFileCache(FileObject defaultsFile) throws IOException {
 47  0
         return new FileCache(defaultsFile);
 48  
     }
 49  
 
 50  
     public WebslingerContainer getContainer() {
 51  3390
         return container;
 52  
     }
 53  
 
 54  
     public FileObject getServletFile() {
 55  4130
         return servletFile;
 56  
     }
 57  
 
 58  
     public String getType() throws IOException {
 59  1562
         return (String) getAttribute("type");
 60  
     }
 61  
 
 62  
     public abstract FileObject getFile() throws IOException;
 63  
     public abstract boolean exists() throws IOException;
 64  
     public abstract String getContentType() throws IOException;
 65  
 
 66  
     public boolean attributeExists(String name) throws IOException {
 67  0
         return getObject().getAttributeInternal(name) != null;
 68  
     }
 69  
 
 70  
     public Object getAttribute(String name) throws IOException {
 71  10858
         return getObject().getAttributeInternal(name);
 72  
     }
 73  
 
 74  
     protected Object getAttributeInternal(String name) throws IOException {
 75  0
         return getObject().getAttributeInternal(name);
 76  
     }
 77  
 
 78  
     public Map<String, ?> getDefaultAttributes() throws IOException {
 79  11
         return getObject().getDefaultAttributes();
 80  
     }
 81  
 
 82  
     public String[] getSplitAttribute(String name) throws IOException {
 83  231
         return getSplitAttribute(name, null);
 84  
     }
 85  
 
 86  
     public String[] getSplitAttribute(String name, String def) throws IOException {
 87  1835
         return getObject().getSplitAttribute(name, def);
 88  
     }
 89  
 
 90  
     public Map<String, ?> getAttributes() throws IOException {
 91  0
         return getObject().getAttributes();
 92  
     }
 93  
 
 94  
     public <T> T getCachedItem(Class owner, String name, Creator<T> creator) throws IOException, ServletException {
 95  
         try {
 96  0
             return getObject().getItem(owner, name, creator);
 97  0
         } catch (RuntimeException e) {
 98  0
             throw e;
 99  0
         } catch (IOException e) {
 100  0
             throw e;
 101  0
         } catch (ServletException e) {
 102  0
             throw e;
 103  0
         } catch (Exception e) {
 104  0
             throw (ServletException) new ServletException(e.getMessage()).initCause(e);
 105  
         }
 106  
     }
 107  
 
 108  
     public String toString() {
 109  0
         return "FI<" + servletFile + '>';
 110  
     }
 111  
 
 112  3111
     public static abstract class FileInfoVFSDelegate<T extends FileInfo, C> extends VFSDelegateProxy<Object, T, Object, C> {
 113  
         protected FileInfoVFSDelegate(VFSDelegate<Object, Object, C> vfsDelegate) {
 114  52
             super(vfsDelegate, Object.class);
 115  52
         }
 116  
 
 117  
         protected Object getReal(FileInfo fi) throws IOException {
 118  0
             throw new UnsupportedOperationException(getClass() + "|" + fi);
 119  
         }
 120  
 
 121  
         public FileInfo getId(FileInfo fi) throws IOException {
 122  1470
             return fi;
 123  
         }
 124  
 
 125  
         public String getString(FileInfo fi) throws IOException {
 126  281
             return fi.getContainer().getWebslingerServletContext().getInvoker().convertToString(null, getReal(fi));
 127  
         }
 128  
 
 129  
         public InputStream getStream(FileInfo fi) throws IOException {
 130  0
             return fi.getContainer().getWebslingerServletContext().getInvoker().convertToStream(null, getReal(fi));
 131  
         }
 132  
 
 133  
         public boolean attributeExists(FileInfo fi, String name) throws IOException {
 134  0
             return fi.attributeExists(name);
 135  
         }
 136  
 
 137  
         public Object getAttribute(FileInfo fi, String name) throws IOException {
 138  0
             return fi.getAttribute(name);
 139  
         }
 140  
     }
 141  
 
 142  852
     protected class SplitAttributeTTLObject extends TTLObject<String[]> {
 143  
         protected final String name;
 144  
         protected final String def;
 145  
 
 146  508
         protected SplitAttributeTTLObject(String name, String def) {
 147  508
             this.name = name;
 148  508
             this.def = def;
 149  508
         }
 150  
 
 151  
         protected String[] load(String[] old) throws IOException {
 152  852
             FileInfo.this.getObject();
 153  852
             String value = (String) getAttribute(name);
 154  852
             if (value == null) {
 155  826
                 if (def == null) return null;
 156  0
                 value = def;
 157  
             }
 158  26
             return value.split("[, ]");
 159  
         }
 160  
     }
 161  
 
 162  
     protected class FileCache {
 163  895
         private final ConcurrentHashMap<String, SplitAttributeTTLObject> splitCache = new ConcurrentHashMap<String, SplitAttributeTTLObject>();
 164  895
         private final ConcurrentFreezableCache<ItemKey, Object> itemCache = new ConcurrentFreezableCache<ItemKey, Object>(FileInfo.class, "cache", null, ConcurrentFreezableCache.HARD) {
 165  
             protected Object createValue(Object id, ItemKey key) throws Exception {
 166  0
                 return ((FreezableItemKey) id).createValue(key);
 167  
             }
 168  
         };
 169  
 
 170  
         public final FileObject defaultsFile;
 171  
 
 172  895
         protected FileCache(FileObject defaultsFile) {
 173  895
             this.defaultsFile = defaultsFile;
 174  895
         }
 175  
 
 176  
         protected String[] getSplitAttribute(String name, String def) throws IOException {
 177  1834
             SplitAttributeTTLObject spliter = splitCache.get(name);
 178  1840
             if (spliter == null) {
 179  508
                 spliter = new SplitAttributeTTLObject(name, def);
 180  508
                 splitCache.put(name, spliter);
 181  
             }
 182  1836
             return spliter.getObject();
 183  
         }
 184  
 
 185  
         protected <T> T getItem(Class owner, String name, Creator<T> creator) throws Exception {
 186  0
             return (T) itemCache.get(new FreezableItemKey<T>(owner, name, creator));
 187  
         }
 188  
 
 189  
         protected Object getAttributeInternal(String name) throws IOException {
 190  9687
             if (defaultsFile != null) {
 191  
                 //System.err.println("checking default(" + defaultsFile + ')');
 192  9691
                 if (defaultsFile.exists()) {
 193  9078
                     if (defaultsFile.getContent().attributeExists(name)) return defaultsFile.getContent().getAttribute(name);
 194  
                 }
 195  4292
                 FileObject parent = defaultsFile.getParent();
 196  
                 //System.err.println("checking parent(" + parent + ')');
 197  4297
                 if (parent.exists()) return parent.getContent().getAttribute(name);
 198  
             }
 199  373
             return null;
 200  
         }
 201  
 
 202  
         protected Map<String, ?> getDefaultAttributes() throws IOException {
 203  11
             Map<String, ?> attributes = new HashMap<String, Object>();
 204  11
             if (defaultsFile != null) {
 205  11
                 FileObject parent = defaultsFile.getParent();
 206  
                 //System.err.println("checking parent(" + parent + ')');
 207  11
                 if (parent.exists()) attributes.putAll(parent.getContent().getAttributes());
 208  
                 //System.err.println("checking default(" + defaultsFile + ')');
 209  11
                 if (defaultsFile.exists()) attributes.putAll(defaultsFile.getContent().getAttributes());
 210  
             }
 211  11
             return attributes;
 212  
         }
 213  
 
 214  
         protected Map<String, ?> getAttributes() throws IOException {
 215  0
             return getDefaultAttributes();
 216  
         }
 217  
     }
 218  
 
 219  
     private static final class ItemKey {
 220  
         protected final Class owner;
 221  
         protected final String name;
 222  
 
 223  0
         protected ItemKey(Class owner, String name) {
 224  0
             this.owner = owner;
 225  0
             this.name = name;
 226  0
         }
 227  
 
 228  
         public int hashCode() {
 229  0
             return hashCodeHelper(owner) ^ hashCodeHelper(name) ^ ItemKey.class.hashCode();
 230  
         }
 231  
 
 232  
         public boolean equals(Object o) {
 233  0
             if (!(o instanceof ItemKey)) return false;
 234  0
             ItemKey other = (ItemKey) o;
 235  0
             return equalsHelper(owner, other.owner) && equalsHelper(name, other.name);
 236  
         }
 237  
 
 238  
         public String toString() {
 239  0
             return "ItemKey(" + owner + ":" + name + ")";
 240  
         }
 241  
     }
 242  
 
 243  0
     private final class FreezableItemKey<T> implements Freezable<ItemKey> {
 244  
         private final ItemKey ik;
 245  
         private final Creator<T> creator;
 246  
 
 247  0
         protected FreezableItemKey(Class owner, String name, Creator<T> creator) {
 248  0
             this.ik = new ItemKey(owner, name);
 249  0
             this.creator = creator;
 250  0
         }
 251  
 
 252  
         public ItemKey freeze() {
 253  0
             return ik;
 254  
         }
 255  
 
 256  
         protected T createValue(ItemKey key) throws Exception {
 257  0
             return creator.createValue(FileInfo.this, ik.name);
 258  
         }
 259  
     }
 260  
 
 261  
     public interface Creator<V> {
 262  
         V createValue(FileInfo fi, String name) throws IOException, ServletException;
 263  
     }
 264  
 
 265  
     public static class ReadObjectCreator implements Creator<Object> {
 266  
         private final String typeAttribute;
 267  
         private final String defaultType;
 268  
 
 269  0
         public ReadObjectCreator(String typeAttribute, String defaultType) {
 270  0
             this.typeAttribute = typeAttribute;
 271  0
             this.defaultType = defaultType;
 272  0
         }
 273  
 
 274  
         public Object createValue(FileInfo fi, String name) throws IOException {
 275  0
             String type = (String) fi.getAttribute(typeAttribute);
 276  0
             if (type == null) type = defaultType;
 277  0
             return IOUtil.readObject(type, fi.getFile().getContent().getInputStream());
 278  
         }
 279  
     }
 280  
 }