/* $Id$
*
* Copyright (c) 2008 by Brent Easton and Joel Uckelman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.build.module.metadata;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import VASSAL.build.GameModule;
import VASSAL.build.module.GameState;
import VASSAL.tools.imports.ImportAction;
import VASSAL.tools.io.IOUtils;
public class MetaDataFactory {
private static final Logger logger =
LoggerFactory.getLogger(MetaDataFactory.class);
protected static final String BUILDFILE_MODULE_ELEMENT1 = "VASSAL.launch.BasicModule";
protected static final String BUILDFILE_MODULE_ELEMENT2 = "VASSAL.build.GameModule";
protected static final String BUILDFILE_EXTENSION_ELEMENT = "VASSAL.build.module.ModuleExtension";
/**
* Factory method to build and return an appropriate MetaData class based on
* the contents of the file. Return null if the file is not a Zip archive, or
* it is not a VASSAL Module, Extension or Save Game.
*
* @param file
* metadata file
* @return MetaData object
*/
public static AbstractMetaData buildMetaData(File file) {
// Check the file exists and is a file
if (file == null || !file.exists() || !file.isFile())
return null;
ZipFile zip = null;
try {
// Check it is a Zip file
zip = new ZipFile(file);
// Check if it is a Save Game file
ZipEntry entry = zip.getEntry(GameState.SAVEFILE_ZIP_ENTRY);
if (entry != null) {
return new SaveMetaData(zip);
}
// Check if it has a buildFile
ZipEntry buildFileEntry = zip.getEntry(GameModule.BUILDFILE);
if (buildFileEntry == null) {
return null;
}
// It's either a module or an Extension, check for existence of metadata
entry = zip.getEntry(ExtensionMetaData.ZIP_ENTRY_NAME);
if (entry != null) {
return new ExtensionMetaData(zip);
}
entry = zip.getEntry(ModuleMetaData.ZIP_ENTRY_NAME);
if (entry != null) {
return new ModuleMetaData(zip);
}
// read the first few lines of the buildFile
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(zip
.getInputStream(buildFileEntry)));
for (int i = 0; i < 10; i++) {
final String s = br.readLine();
if (s.indexOf(BUILDFILE_MODULE_ELEMENT1) > 0
|| s.indexOf(BUILDFILE_MODULE_ELEMENT2) > 0) {
br.close();
return new ModuleMetaData(zip);
}
else if (s.indexOf(BUILDFILE_EXTENSION_ELEMENT) > 0) {
br.close();
return new ExtensionMetaData(zip);
}
}
br.close();
}
finally {
IOUtils.closeQuietly(br);
}
zip.close();
}
catch (ZipException e) {
// It is not a Zip file, check for an Importable file
return ImportAction.buildMetaData(file);
}
catch (IOException e) {
logger.error("", e);
}
finally {
IOUtils.closeQuietly(zip);
}
return null;
}
}