001/*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020package org.crsh.util;
021
022import org.crsh.command.CommandCreationException;
023import org.crsh.shell.ErrorType;
024import org.crsh.vfs.Resource;
025
026import java.io.UnsupportedEncodingException;
027
028public abstract class AbstractClassCache<T> {
029
030  /** . */
031  private final ClassFactory<T> classFactory;
032
033  protected AbstractClassCache(ClassFactory<T> classFactory) {
034    this.classFactory = classFactory;
035  }
036  
037  protected abstract TimestampedObject<Class<? extends T>> loadClass(String name);
038
039  protected abstract void saveClass(String name, TimestampedObject<Class<? extends T>> clazz);
040
041  protected abstract Resource getResource(String name);
042
043  public TimestampedObject<Class<? extends T>> getClass(String name) throws CommandCreationException, NullPointerException {
044    if (name == null) {
045      throw new NullPointerException("No null argument allowed");
046    }
047
048    TimestampedObject<Class<? extends T>> providerRef = loadClass(name);
049
050    //
051    Resource script = getResource(name);
052
053    //
054    if (script != null) {
055      if (providerRef != null) {
056        if (script.getTimestamp() != providerRef.getTimestamp()) {
057          providerRef = null;
058        }
059      }
060
061      //
062      if (providerRef == null) {
063
064        //
065        String source;
066        try {
067          source = new String(script.getContent(), "UTF-8");
068        }
069        catch (UnsupportedEncodingException e) {
070          throw new CommandCreationException(name, ErrorType.INTERNAL, "Could not compile command script " + name, e);
071        }
072
073        //
074        Class<? extends T> clazz = classFactory.parse(name, source);
075        providerRef = new TimestampedObject<Class<? extends T>>(script.getTimestamp(), clazz);
076        saveClass(name, providerRef);
077      }
078    }
079
080    //
081    if (providerRef == null) {
082      return null;
083    }
084
085    //
086    return providerRef;
087  }
088}