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 */
019package org.crsh.lang.impl;
020
021import org.crsh.lang.spi.Compiler;
022import org.crsh.lang.spi.Language;
023import org.crsh.lang.spi.Repl;
024import org.crsh.plugin.CRaSHPlugin;
025import org.crsh.plugin.PluginContext;
026import org.crsh.shell.impl.command.ShellSession;
027
028import java.lang.reflect.Constructor;
029import java.util.concurrent.atomic.AtomicReference;
030
031/**
032 * A command manager that is able to load a command manager via reflection.
033 *
034 * @author Julien Viet
035 */
036public class LanguageProxy extends CRaSHPlugin<Language> implements Language {
037
038  /** . */
039  private final AtomicReference<Language> real = new AtomicReference<Language>();
040
041  /** . */
042  private final String name;
043
044  /** . */
045  private final String className;
046
047  public LanguageProxy(String name, String className) {
048    this.name = name;
049    this.className = className;
050  }
051
052  @Override
053  public Language getImplementation() {
054    return this;
055  }
056
057  @Override
058  public void init() {
059    try {
060      Class<Language> mgrClass = (Class<Language>)getClass().getClassLoader().loadClass(className);
061      Constructor<Language> mgrCtor = mgrClass.getConstructor(PluginContext.class);
062      Language mgr = mgrCtor.newInstance(getContext());
063      real.set(mgr);
064    }
065    catch (Exception e) {
066      log.info("Plugin is inactive");
067    }
068    catch (NoClassDefFoundError e) {
069      log.info("Plugin is inactive");
070    }
071  }
072
073  @Override
074  public String getName() {
075    return name;
076  }
077
078  @Override
079  public String getDisplayName() {
080    return real.get() != null ? real.get().getDisplayName() : "";
081  }
082
083  @Override
084  public boolean isActive() {
085    return real.get() != null;
086  }
087
088  @Override
089  public Repl getRepl() {
090    Language lang = real.get();
091    if (lang != null) {
092      return lang.getRepl();
093    } else {
094      throw new IllegalStateException(name + " language is not available");
095    }
096  }
097
098  @Override
099  public Compiler getCompiler() {
100    Language lang = real.get();
101    if (lang != null) {
102      return lang.getCompiler();
103    } else {
104      throw new IllegalStateException(name + " language is not available");
105    }
106  }
107
108  @Override
109  public void init(ShellSession session) {
110    Language lang = real.get();
111    if (lang != null) {
112      lang.init(session);
113    } else {
114      throw new IllegalStateException(name + " language is not available");
115    }
116  }
117
118  @Override
119  public void destroy(ShellSession session) {
120    Language lang = real.get();
121    if (lang != null) {
122      lang.destroy(session);
123    } else {
124      throw new IllegalStateException(name + " language is not available");
125    }
126  }
127}