/*
* This file is part of aion-emu <aion-emu.com>.
*
* aion-emu is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* aion-emu is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with aion-emu. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.commons.services;
import java.io.File;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javolution.util.FastMap;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import com.aionemu.commons.scripting.scriptmanager.ScriptManager;
/**
* Script Service class that is designed to manage all loaded contexts
*
* @author SoulKeeper
*/
public class ScriptService
{
/**
* Logger
*/
private static final Logger log = Logger.getLogger(ScriptService.class);
/**
* Container for ScriptManagers, sorted by file
*/
private final Map<File, ScriptManager> map = new FastMap<File, ScriptManager>().shared();
/**
* Loads script descriptor from given directory or file
*
* @param file
* directory or file
* @throws RuntimeException
* if failed to load script descriptor
*/
public void load(String file) throws RuntimeException
{
load(new File(file));
}
/**
* Loads script descriptor from given file or directory
*
* @param file
* file that has to be loaded
* @throws RuntimeException
* if something went wrong
*/
public void load(File file) throws RuntimeException
{
if(file.isFile())
{
loadFile(file);
}
else if(file.isDirectory())
{
loadDir(file);
}
}
/**
* Load script descriptor from given file
*
* @param file
* script descriptor
*/
private void loadFile(File file)
{
if(map.containsKey(file))
{
throw new IllegalArgumentException("ScriptManager by file:" + file + " already loaded");
}
ScriptManager sm = new ScriptManager();
try
{
sm.load(file);
}
catch(Exception e)
{
log.error(e);
throw new RuntimeException(e);
}
map.put(file, sm);
}
/**
* Loads all files from given directory
*
* @param dir
* directory to scan for files
*/
private void loadDir(File dir)
{
for(Object file : FileUtils.listFiles(dir, new String[] { "xml" }, false))
{
loadFile((File) file);
}
}
/**
* Unloads given script descriptor
*
* @param file
* script descriptor
* @throws IllegalArgumentException
* if descriptor is not loaded
*/
public void unload(File file) throws IllegalArgumentException
{
ScriptManager sm = map.remove(file);
if(sm == null)
{
throw new IllegalArgumentException("ScriptManager by file " + file + " is not loaded.");
}
sm.shutdown();
}
/**
* Reloads given script descriptor
*
* @param file
* Script Descriptro
* @throws IllegalArgumentException
* if descriptor is not loaded
*/
public void reload(File file) throws IllegalArgumentException
{
ScriptManager sm = map.get(file);
if(sm == null)
{
throw new IllegalArgumentException("ScriptManager by file " + file + " is not loaded.");
}
sm.reload();
}
/**
* Adds script manager to script service.<br>
* Should be used if scriptManager uses custom loading logic for scripts.
*
* @param scriptManager
* Script manager object
* @param file
* script descriptor file
*/
public void addScriptManager(ScriptManager scriptManager, File file)
{
if(map.containsKey(file))
{
throw new IllegalArgumentException("ScriptManager by file " + file + " is already loaded.");
}
map.put(file, scriptManager);
}
/**
* Returns unmodifiable map with loaded script managers
*
* @return unmodifiable map
*/
public Map<File, ScriptManager> getLoadedScriptManagers()
{
return Collections.unmodifiableMap(map);
}
/**
* Broadcast shutdown to all attached Script Managers.
*/
public void shutdown()
{
for(Iterator<Entry<File, ScriptManager>> it = this.map.entrySet().iterator(); it.hasNext();)
{
try
{
it.next().getValue().shutdown();
}
catch(Exception e)
{
log.warn("An exception occured during shudown procedure.", e);
}
it.remove();
}
}
}