.
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.service.core.vfs;
+
+import java.net.URI;
+
+import org.apache.commons.vfs.FileObject;
+
+import com.l2jserver.service.Service;
+
+/**
+ * The VFS service provides access to files. With this service is possible to
+ * change the location of files.
+ *
+ * @author Rogiel
+ */
+public interface VFSService extends Service {
+ /**
+ * Resolves an file. If the file cannot be resolved, null will be returned.
+ *
+ * Please note that event if the file DOES NOT exists a valid object will be
+ * returned.
+ *
+ * @param uri
+ * the file uri
+ * @return the resolved file. Will return null if could not resolve.
+ */
+ FileObject resolve(URI uri);
+
+ /**
+ * Resolves an file. If the file cannot be resolved, null will be returned.
+ *
+ * Please note that event if the file DOES NOT exists a valid object will be
+ * returned.
+ *
+ * @param uri
+ * the file uri as an string
+ * @return the resolved file. Will return null if could not resolve.
+ */
+ FileObject resolve(String uri);
+}
diff --git a/src/main/java/com/l2jserver/service/core/vfs/VFSServiceImpl.java b/src/main/java/com/l2jserver/service/core/vfs/VFSServiceImpl.java
new file mode 100644
index 000000000..f902003ca
--- /dev/null
+++ b/src/main/java/com/l2jserver/service/core/vfs/VFSServiceImpl.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.service.core.vfs;
+
+import java.io.File;
+import java.net.URI;
+
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemManager;
+import org.apache.commons.vfs.impl.DefaultFileSystemManager;
+import org.apache.commons.vfs.impl.StandardFileSystemManager;
+
+import com.l2jserver.service.AbstractService;
+import com.l2jserver.service.ServiceStartException;
+import com.l2jserver.service.ServiceStopException;
+
+/**
+ * Default implementation for VFS system
+ *
+ * @author Rogiel
+ */
+public class VFSServiceImpl extends AbstractService implements VFSService {
+ /**
+ * The CommonsVFS {@link FileSystemManager}
+ */
+ private DefaultFileSystemManager manager;
+
+ @Override
+ protected void doStart() throws ServiceStartException {
+ manager = new StandardFileSystemManager();
+ try {
+ manager.init();
+ manager.setBaseFile(new File("./"));
+ } catch (FileSystemException e) {
+ manager = null;
+ throw new ServiceStartException(e);
+ }
+ }
+
+ @Override
+ public FileObject resolve(URI uri) {
+ return resolve(uri.toString());
+ }
+
+ @Override
+ public FileObject resolve(String uri) {
+ try {
+ return manager.resolveFile(uri);
+ } catch (FileSystemException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected void doStop() throws ServiceStopException {
+ try {
+ manager.getBaseFile().close();
+ } catch (FileSystemException e) {
+ throw new ServiceStopException(e);
+ } finally {
+ manager = null;
+ }
+ }
+}
diff --git a/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java b/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java
index a86479e92..72e5abd19 100644
--- a/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java
+++ b/src/main/java/com/l2jserver/service/game/template/XMLTemplateService.java
@@ -16,8 +16,8 @@
*/
package com.l2jserver.service.game.template;
-import java.io.File;
-import java.util.Collection;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.List;
import java.util.Map;
@@ -30,7 +30,7 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs.FileObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,17 +48,21 @@ import com.l2jserver.service.ServiceStartException;
import com.l2jserver.service.ServiceStopException;
import com.l2jserver.service.configuration.ConfigurationService;
import com.l2jserver.service.core.LoggingService;
+import com.l2jserver.service.core.vfs.VFSService;
import com.l2jserver.util.factory.CollectionFactory;
import com.l2jserver.util.jaxb.CharacterTemplateIDAdapter;
import com.l2jserver.util.jaxb.ItemTemplateIDAdapter;
import com.l2jserver.util.jaxb.NPCTemplateIDAdapter;
import com.l2jserver.util.jaxb.TeleportationTemplateIDAdapter;
+import com.l2jserver.util.vfs.ExtensionFileSelector;
-@Depends({ LoggingService.class, ConfigurationService.class })
+@Depends({ LoggingService.class, VFSService.class, ConfigurationService.class })
public class XMLTemplateService extends AbstractService implements
TemplateService {
private final Logger log = LoggerFactory.getLogger(this.getClass());
+ private final VFSService vfsService;
+
private final XMLTemplateServiceConfiguration config;
private final NPCTemplateIDAdapter npcTemplateIdAdapter;
private final ItemTemplateIDAdapter itemTemplateIdAdapter;
@@ -72,11 +76,13 @@ public class XMLTemplateService extends AbstractService implements
private Map templates = CollectionFactory.newMap();
@Inject
- public XMLTemplateService(ConfigurationService configService,
+ public XMLTemplateService(final VFSService vfsService,
+ ConfigurationService configService,
NPCTemplateIDAdapter npcTemplateIdAdapter,
ItemTemplateIDAdapter itemTemplateIdAdapter,
CharacterTemplateIDAdapter charIdTemplateAdapter,
TeleportationTemplateIDAdapter teleportationIdTemplateAdapter) {
+ this.vfsService = vfsService;
this.config = configService.get(XMLTemplateServiceConfiguration.class);
this.npcTemplateIdAdapter = npcTemplateIdAdapter;
this.itemTemplateIdAdapter = itemTemplateIdAdapter;
@@ -91,7 +97,7 @@ public class XMLTemplateService extends AbstractService implements
context = JAXBContext.newInstance(CharacterTemplate.class,
NPCTemplate.class, ItemTemplate.class,
TeleportationTemplateContainer.class);
-
+
log.debug("Creating Unmarshaller instance");
unmarshaller = context.createUnmarshaller();
@@ -104,24 +110,33 @@ public class XMLTemplateService extends AbstractService implements
unmarshaller.setAdapter(TeleportationTemplateIDAdapter.class,
teleportationIdTemplateAdapter);
- @SuppressWarnings("unchecked")
- Collection files = FileUtils
- .listFiles(config.getTemplateDirectory(),
- new String[] { "xml" }, true);
- log.debug("Located {} XML template files", files.size());
- for (final File file : files) {
- log.debug("Loading template {}", file);
+ final FileObject root = vfsService.resolve(config
+ .getTemplateDirectory());
+
+ log.info("Scanning {} for XML templates", root);
+
+ FileObject[] files = root.findFiles(ExtensionFileSelector
+ .ext("xml"));
+
+ log.info("Located {} XML template files", files.length);
+ for (final FileObject file : files) {
loadTemplate(file);
}
- TeleportationTemplateContainer container = (TeleportationTemplateContainer) unmarshaller
- .unmarshal(new File(config.getTemplateDirectory(),
- "../teleports.xml"));
- for (final TeleportationTemplate template : container.templates) {
- templates.put(template.getID(), template);
+ final FileObject teleportsXml = root.getParent().resolveFile(
+ "teleports.xml");
+ final InputStream in = teleportsXml.getContent().getInputStream();
+ try {
+ TeleportationTemplateContainer container = (TeleportationTemplateContainer) unmarshaller
+ .unmarshal(in);
+ for (final TeleportationTemplate template : container.templates) {
+ templates.put(template.getID(), template);
+ }
+ } finally {
+ in.close();
}
} catch (JAXBException e) {
- e.printStackTrace();
- System.exit(0);
+ throw new ServiceStartException(e);
+ } catch (IOException e) {
throw new ServiceStartException(e);
}
}
@@ -133,11 +148,18 @@ public class XMLTemplateService extends AbstractService implements
return (T) templates.get(id);
}
- public void loadTemplate(File file) throws JAXBException {
+ public void loadTemplate(FileObject file) throws JAXBException, IOException {
Preconditions.checkNotNull(file, "file");
- final Template> template = (Template>) unmarshaller.unmarshal(file);
- if (template.getID() != null)
- templates.put(template.getID(), template);
+ log.debug("Loading template {}", file);
+ final InputStream in = file.getContent().getInputStream();
+ try {
+ final Template> template = (Template>) unmarshaller
+ .unmarshal(in);
+ if (template.getID() != null)
+ templates.put(template.getID(), template);
+ } finally {
+ in.close();
+ }
}
public void removeTemplate(Template> template) {
diff --git a/src/main/java/com/l2jserver/service/game/template/XMLTemplateServiceConfiguration.java b/src/main/java/com/l2jserver/service/game/template/XMLTemplateServiceConfiguration.java
index 6a91fc2e1..696d4e75a 100644
--- a/src/main/java/com/l2jserver/service/game/template/XMLTemplateServiceConfiguration.java
+++ b/src/main/java/com/l2jserver/service/game/template/XMLTemplateServiceConfiguration.java
@@ -16,16 +16,16 @@
*/
package com.l2jserver.service.game.template;
-import java.io.File;
+import java.net.URI;
import com.l2jserver.service.configuration.Configuration;
import com.l2jserver.service.configuration.Configuration.ConfigurationName;
@ConfigurationName("template")
public interface XMLTemplateServiceConfiguration extends Configuration {
- @ConfigurationPropertyGetter(name = "template.directory", defaultValue = "data/templates")
- File getTemplateDirectory();
+ @ConfigurationPropertyGetter(name = "template.directory", defaultValue = "zip:data/templates.zip")
+ URI getTemplateDirectory();
@ConfigurationPropertySetter(name = "template.directory")
- void setTemplateDirectory(File file);
+ void setTemplateDirectory(URI file);
}
diff --git a/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java b/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java
index 9a0aa18e9..b0a143c4f 100644
--- a/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java
+++ b/src/main/java/com/l2jserver/util/transformer/TransformerFactory.java
@@ -18,6 +18,8 @@ package com.l2jserver.util.transformer;
import java.io.File;
import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.URL;
import com.l2jserver.util.transformer.impl.BooleanTransformer;
import com.l2jserver.util.transformer.impl.ByteTransformer;
@@ -29,6 +31,8 @@ import com.l2jserver.util.transformer.impl.InetSocketAddressTransformer;
import com.l2jserver.util.transformer.impl.IntegerTransformer;
import com.l2jserver.util.transformer.impl.LongTransformer;
import com.l2jserver.util.transformer.impl.ShortTransformer;
+import com.l2jserver.util.transformer.impl.URITransformer;
+import com.l2jserver.util.transformer.impl.URLTransformer;
/**
* The {@link TransformerFactory} return the transformer instance for any given
@@ -65,6 +69,10 @@ public class TransformerFactory {
return FileTransformer.SHARED_INSTANCE;
} else if (type == Class.class) {
return ClassTransformer.SHARED_INSTANCE;
+ } else if (type == URI.class) {
+ return URITransformer.SHARED_INSTANCE;
+ } else if (type == URL.class) {
+ return URLTransformer.SHARED_INSTANCE;
}
return null;
}
diff --git a/src/main/java/com/l2jserver/util/transformer/impl/URITransformer.java b/src/main/java/com/l2jserver/util/transformer/impl/URITransformer.java
new file mode 100644
index 000000000..166c83f34
--- /dev/null
+++ b/src/main/java/com/l2jserver/util/transformer/impl/URITransformer.java
@@ -0,0 +1,46 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.util.transformer.impl;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import com.l2jserver.util.transformer.Transformer;
+
+/**
+ * Transform an {@link URI} into an string.
+ *
+ * @author Rogiel
+ */
+public class URITransformer implements Transformer {
+ public static final URITransformer SHARED_INSTANCE = new URITransformer();
+
+ @Override
+ public String transform(URI value) {
+ return value.toString();
+ }
+
+ @Override
+ public URI untransform(String value) {
+ try {
+ return new URI(value);
+ } catch (URISyntaxException e) {
+ return null;
+ }
+ }
+
+}
diff --git a/src/main/java/com/l2jserver/util/transformer/impl/URLTransformer.java b/src/main/java/com/l2jserver/util/transformer/impl/URLTransformer.java
new file mode 100644
index 000000000..41c724d04
--- /dev/null
+++ b/src/main/java/com/l2jserver/util/transformer/impl/URLTransformer.java
@@ -0,0 +1,47 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.util.transformer.impl;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+
+import com.l2jserver.util.transformer.Transformer;
+
+/**
+ * Transform an {@link URI} into an string.
+ *
+ * @author Rogiel
+ */
+public class URLTransformer implements Transformer {
+ public static final URLTransformer SHARED_INSTANCE = new URLTransformer();
+
+ @Override
+ public String transform(URL value) {
+ return value.toString();
+ }
+
+ @Override
+ public URL untransform(String value) {
+ try {
+ return new URL(value);
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+}
diff --git a/src/main/java/com/l2jserver/util/vfs/ExtensionFileSelector.java b/src/main/java/com/l2jserver/util/vfs/ExtensionFileSelector.java
new file mode 100644
index 000000000..ad6122908
--- /dev/null
+++ b/src/main/java/com/l2jserver/util/vfs/ExtensionFileSelector.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of l2jserver .
+ *
+ * l2jserver 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.
+ *
+ * l2jserver 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 l2jserver. If not, see .
+ */
+package com.l2jserver.util.vfs;
+
+import java.util.Arrays;
+
+import org.apache.commons.vfs.FileSelectInfo;
+import org.apache.commons.vfs.FileSelector;
+import org.apache.commons.vfs.FileType;
+
+/**
+ * This selector will select all FILES that has an given extension.
+ *
+ * @author Rogiel
+ */
+public class ExtensionFileSelector implements FileSelector {
+ private final String[] extensions;
+ private final boolean descendents;
+
+ public ExtensionFileSelector(String... extensions) {
+ this(true, extensions);
+ }
+
+ public ExtensionFileSelector(boolean descendents, String... extensions) {
+ this.descendents = descendents;
+ this.extensions = extensions;
+ Arrays.sort(extensions);
+ }
+
+ @Override
+ public boolean includeFile(FileSelectInfo file) throws Exception {
+ if (file.getFile().getType() != FileType.FILE)
+ return false;
+ return (Arrays.binarySearch(extensions, file.getFile().getName()
+ .getExtension()) >= 0);
+ }
+
+ @Override
+ public boolean traverseDescendents(FileSelectInfo file) throws Exception {
+ return descendents;
+ }
+
+ public static final ExtensionFileSelector ext(String... extensions) {
+ return new ExtensionFileSelector(extensions);
+ }
+}