From a162b9d6d5e48da08361c8e7b9e5de641625b81a Mon Sep 17 00:00:00 2001 From: Rogiel Date: Thu, 26 May 2011 19:06:37 -0300 Subject: [PATCH] VFSService and pom.xml updated Signed-off-by: Rogiel --- config/database.properties | 2 +- config/template-compiled.xml | 24 ---- config/template.properties | 2 +- data/sample/skill.xml | 32 ++++++ pom.xml | 105 ++++++++++-------- src/assembly/distribution-bin.xml | 9 +- src/assembly/distribution-src.xml | 2 - .../l2jserver/model/template/NPCTemplate.java | 3 - .../com/l2jserver/service/ServiceModule.java | 3 + .../service/core/vfs/VFSService.java | 55 +++++++++ .../service/core/vfs/VFSServiceImpl.java | 79 +++++++++++++ .../game/template/XMLTemplateService.java | 70 ++++++++---- .../XMLTemplateServiceConfiguration.java | 8 +- .../util/transformer/TransformerFactory.java | 8 ++ .../util/transformer/impl/URITransformer.java | 46 ++++++++ .../util/transformer/impl/URLTransformer.java | 47 ++++++++ .../util/vfs/ExtensionFileSelector.java | 60 ++++++++++ 17 files changed, 450 insertions(+), 105 deletions(-) delete mode 100644 config/template-compiled.xml create mode 100644 data/sample/skill.xml create mode 100644 src/main/java/com/l2jserver/service/core/vfs/VFSService.java create mode 100644 src/main/java/com/l2jserver/service/core/vfs/VFSServiceImpl.java create mode 100644 src/main/java/com/l2jserver/util/transformer/impl/URITransformer.java create mode 100644 src/main/java/com/l2jserver/util/transformer/impl/URLTransformer.java create mode 100644 src/main/java/com/l2jserver/util/vfs/ExtensionFileSelector.java diff --git a/config/database.properties b/config/database.properties index 040f4b19e..6bacfe2f5 100644 --- a/config/database.properties +++ b/config/database.properties @@ -1,4 +1,4 @@ jdbc.mysql.url = jdbc:mysql://localhost/l2jserver2 jdbc.mysql.driver = com.mysql.jdbc.Driver -jdbc.mysql.username = l2j123 +jdbc.mysql.username = l2j jdbc.mysql.password = changeme \ No newline at end of file diff --git a/config/template-compiled.xml b/config/template-compiled.xml deleted file mode 100644 index ac8de09d0..000000000 --- a/config/template-compiled.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - com.l2jserver.service.game.scripting.impl.compiled.PrecompiledScriptCompiler - \ No newline at end of file diff --git a/config/template.properties b/config/template.properties index 7b36a0cd3..b431db32e 100644 --- a/config/template.properties +++ b/config/template.properties @@ -1 +1 @@ -#template.descriptor = config/template-compiled.xml \ No newline at end of file +template.directory = data/templates \ No newline at end of file diff --git a/data/sample/skill.xml b/data/sample/skill.xml new file mode 100644 index 000000000..05a8434ca --- /dev/null +++ b/data/sample/skill.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 4430358a8..4905838dc 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,7 @@ 2011 + junit junit @@ -16,12 +17,14 @@ jar test + org.jboss.netty netty 3.2.4.Final runtime + com.google.inject guice @@ -36,6 +39,14 @@ jar runtime + + com.google.inject.extensions + guice-multibindings + 3.0 + jar + runtime + + org.slf4j slf4j-log4j12 @@ -43,6 +54,14 @@ jar runtime + + org.slf4j + jcl-over-slf4j + 1.6.1 + jar + runtime + + mysql mysql-connector-java @@ -50,6 +69,44 @@ jar runtime + + commons-dbcp + commons-dbcp + 20030825.184428 + jar + runtime + + + + net.sf.ehcache + ehcache-core + 2.4.2 + jar + runtime + + + + org.htmlparser + htmlparser + 2.1 + jar + runtime + + + + javolution + javolution + 5.5.1 + jar + runtime + + + com.google.guava + guava + r09 + jar + runtime + javacc javacc @@ -64,13 +121,6 @@ jar runtime - - commons-dbcp - commons-dbcp - 20030825.184428 - jar - runtime - commons-pool commons-pool @@ -92,47 +142,14 @@ jar runtime + - net.sf.ehcache - ehcache-core - 2.4.2 + commons-vfs + commons-vfs + 20050307052300 jar runtime - - com.google.inject.extensions - guice-multibindings - 3.0 - jar - runtime - - - javolution - javolution - 5.5.1 - jar - runtime - - - org.htmlparser - htmlparser - 2.1 - jar - runtime - - - com.google.guava - guava - r09 - jar - runtime - - - org.eclipse.persistence - eclipselink - 2.2.0 - runtime - diff --git a/src/assembly/distribution-bin.xml b/src/assembly/distribution-bin.xml index af50ab371..82478c7fa 100644 --- a/src/assembly/distribution-bin.xml +++ b/src/assembly/distribution-bin.xml @@ -15,8 +15,6 @@ / data/** - README - LICENSE @@ -35,6 +33,13 @@ + + + + + + + /libs diff --git a/src/assembly/distribution-src.xml b/src/assembly/distribution-src.xml index bca3433a0..b3759cdc2 100644 --- a/src/assembly/distribution-src.xml +++ b/src/assembly/distribution-src.xml @@ -16,8 +16,6 @@ data/** src/** - README - LICENSE diff --git a/src/main/java/com/l2jserver/model/template/NPCTemplate.java b/src/main/java/com/l2jserver/model/template/NPCTemplate.java index 1b96a0c50..f5abf5fe1 100644 --- a/src/main/java/com/l2jserver/model/template/NPCTemplate.java +++ b/src/main/java/com/l2jserver/model/template/NPCTemplate.java @@ -28,8 +28,6 @@ import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlValue; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import org.eclipse.persistence.oxm.annotations.XmlCDATA; - import com.l2jserver.model.id.template.ItemTemplateID; import com.l2jserver.model.id.template.NPCTemplateID; import com.l2jserver.model.world.Actor.ActorSex; @@ -240,7 +238,6 @@ public class NPCTemplate extends ActorTemplate { @XmlAttribute(name = "id") protected String id = null; @XmlValue - @XmlCDATA protected String html = null; } diff --git a/src/main/java/com/l2jserver/service/ServiceModule.java b/src/main/java/com/l2jserver/service/ServiceModule.java index 853356f21..1bbd082e9 100644 --- a/src/main/java/com/l2jserver/service/ServiceModule.java +++ b/src/main/java/com/l2jserver/service/ServiceModule.java @@ -25,6 +25,8 @@ import com.l2jserver.service.configuration.ConfigurationService; import com.l2jserver.service.configuration.ProxyConfigurationService; import com.l2jserver.service.core.Log4JLoggingService; import com.l2jserver.service.core.LoggingService; +import com.l2jserver.service.core.vfs.VFSService; +import com.l2jserver.service.core.vfs.VFSServiceImpl; import com.l2jserver.service.database.DatabaseService; import com.l2jserver.service.database.MySQLDatabaseService; import com.l2jserver.service.game.character.CharacterService; @@ -63,6 +65,7 @@ public class ServiceModule extends AbstractModule { bind(ServiceManager.class).in(Scopes.SINGLETON); bind(LoggingService.class).to(Log4JLoggingService.class).in( Scopes.SINGLETON); + bind(VFSService.class).to(VFSServiceImpl.class).in(Scopes.SINGLETON); bind(ConfigurationService.class).to(ProxyConfigurationService.class) .in(Scopes.SINGLETON); bind(CacheService.class).to(EhCacheService.class).in(Scopes.SINGLETON); diff --git a/src/main/java/com/l2jserver/service/core/vfs/VFSService.java b/src/main/java/com/l2jserver/service/core/vfs/VFSService.java new file mode 100644 index 000000000..9d05dc3e2 --- /dev/null +++ b/src/main/java/com/l2jserver/service/core/vfs/VFSService.java @@ -0,0 +1,55 @@ +/* + * 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.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); + } +}