📄 zippeditems.java
字号:
/* * MegaMek - Copyright (C) 2004 Ben Mazur (bmazur@sev.org) * * This program 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 2 of the License, or (at your option) * any later version. * * This program 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. */package megamek.common.util;import java.util.TreeMap;import java.util.Vector;import java.io.File;import java.io.IOException;import java.util.Enumeration;import java.util.zip.ZipEntry;import java.util.zip.ZipException;import java.util.zip.ZipFile;import megamek.common.util.Collections;import megamek.common.util.StringUtil;/** * This class represents a collection of item files present within a ZIP or * JAR file, categorized according to their directories. This collection * will *not* include all files inside of JAR and ZIP files that are located * *inside* the file (i.e. it ignores all nested JAR and ZIP files). * <p/> * Please note, from this point on, the term "ZIP file" will be taken to mean * "ZIP or JAR file", because a JAR file is just a ZIP file with a manifest. * <p/> * Also note, the author plans to eventually handle nested ZIP files, but * the effort was deemed to be unnecessary for the needs that led to the * initial implementation. * * Created on January 18, 2004 * * @author James Damour * @version 1 */public class ZippedItems implements Categorized { /** * The root category name. */ private String rootName; /** * A map of the category names to maps of the item names to the items * Please note that this map includes the root category, * if the root category contains any items. */ private TreeMap categories = new TreeMap( StringUtil.stringComparator() ); /** * The factory that will create <code>ItemFile</code>s for the * contents of the directory hierarchy. */ private ItemFileFactory factory = null; /** * Identify when a name belongs to a ZIP file. * * @param name - the <code>String</code> which may be a ZIP file name. * This value must not be <code>null</code>. * @return <code>true</code> if the name is for a ZIP file. * <code>false</code> if the name is not for a ZIP file. * @throws <code>IllegalArgumentException</code> if <code>name</code> * is null. */ public static boolean isZipName( String name ) { // Convert the file name to upper case, and compare it to image // file extensions. Yeah, it's a bit of a hack, but whatever. String ucName = name.toUpperCase(); return ( ucName.endsWith( "ZIP" ) || //$NON-NLS-1$ ucName.endsWith( "JAR" ) ); //$NON-NLS-1$ } /** * Create a categorized collection of all files within a ZIP file. Please * note, the name of any directories in the ZIP file will be added to the * root category name to create the name of the category names of the * directories. * * @param zipFile - the <code>File</code> object for the ZIP file * containing the image files. All files in this ZIP file, * will be included in this collection, categorized by directory. * This value must not be <code>null</code> and it must be a * ZIP file. * @param categoryName - the <code>String</code> root category name for * this collection. All sub-categories will include this name. * This value may be <code>null</code> (it will be replaced). * @param itemFactory - the <code>ItemFileFactory</code> that will create * <code>ItemFile</code>s for the contents of the directory. * This value must not be <code>null</code>. * @throws <code>IllegalArgumentException</code> if <code>zipFile</code> * or <code>itemFactory</code> is <code>null</code>. * @throws <code>ZipException</code> if there's a ZIP error opening * <code>zipFile</code>. * @throws <code>IOException</code> if there's an IO error opening * <code>zipFile</code>. */ public ZippedItems( File zipFile, String categoryName, ItemFileFactory itemFactory ) throws IllegalArgumentException, ZipException, IOException { // Declare local variables. Enumeration entries = null; ZipEntry entry = null; String catName = null; String name = null; int index; TreeMap category = null; // Validate input. if ( null == zipFile ) { throw new IllegalArgumentException ( "A null ZIP file was passed." ); //$NON-NLS-1$ } if ( null == itemFactory ) { throw new IllegalArgumentException ( "A null item factory was passed." ); //$NON-NLS-1$ } // Save the root category name and the item factory. rootName = categoryName; factory = itemFactory; // Replace a null root category name. if ( null == rootName ) { rootName = zipFile.getName(); } // Open up the ZIP file. ZipFile contents = new ZipFile( zipFile ); /* DEBUG : uncomment this section to debug * System.out.print( "Loading items from "); System.out.println( zipFile.getPath() ); /* DEBUG : uncomment this section to debug */ // We'll need a Vector to hold the ZipEntries and a TreeMap // to map the directory names to the category names. Vector zipEntries = new Vector(); TreeMap names = new TreeMap( StringUtil.stringComparator() ); // Walk through the contents of the ZIP file. entries = contents.entries(); while ( entries.hasMoreElements() ) { // Get the next entry. entry = (ZipEntry) entries.nextElement(); name = entry.getName(); // Is this entry a sub-directory? if ( entry.isDirectory() ) { // Construct the category name for this sub-directory. StringBuffer buffer = new StringBuffer(); buffer.append( rootName ) .append( " : " ) //$NON-NLS-1$ .append( name ); catName = buffer.toString(); // Add the category to the map. categories.put( catName, new TreeMap(StringUtil.stringComparator()) ); // Map the directory name to the category name names.put( name, catName ); } // Is this entry a ZIP or JAR file? else if ( ZippedItems.isZipName( name ) ) { // TODO : implement me!!! System.out.print ( "... found a ZIP file **inside** a ZIP file: " ); //$NON-NLS-1$ System.out.println( name ); } // Does the factory accept this entry? else if ( factory.accept(contents, name) ) { // Save this entry for later. zipEntries.addElement( entry ); } /* DEBUG : uncomment this section to debug * else { System.out.print( "... ignoring " ); System.out.println( name ); } /* DEBUG : uncomment this section to debug */ } // Handle the next ZipEntry. // Add a category for the base directory of the ZIP file. categories.put( rootName, new TreeMap(StringUtil.stringComparator()) ); names.put( rootName, rootName ); // Walk through the ZipEntries and assign them to categories. entries = zipEntries.elements(); while ( entries.hasMoreElements() ) { // Get the next entry. entry = (ZipEntry) entries.nextElement(); // Get the name of the entry. name = entry.getName(); // Should this entry be assigned to a sub-category? index = name.lastIndexOf( "/" ); //$NON-NLS-1$ if ( index < 0 ) { // Nope. Assign it to the root category. catName = rootName; } else { // Yup. Find the sub-category's name. index++; catName = name.substring( 0, index ); catName = (String) names.get( catName ); // We *should* have found category name. if ( null == catName ) { // Assign the ZipEntry to the root category. catName = rootName; } else { // Rename the ZipEntry name = name.substring( index ); } } // Add the entry to the global map. category = (TreeMap) categories.get( catName ); category.put( name, factory.getItemFile(entry, contents) ); } // Handle the next ZipEntry // Remove any category without an entry. entries = Collections.elements( names.values() ); while ( entries.hasMoreElements() ) { // Get the next category name. catName = (String) entries.nextElement(); // Get the named category. category = (TreeMap) categories.get( catName ); // If the category is empty, remove it. if ( category.isEmpty() ) { categories.remove( catName ); } } // Check the next category } /** * Get the names of all the categories. * * @return an <code>Enumeration</code> of <code>String</code> names. * This value will not be <code>null</code>, but it may be empty. */ public Enumeration getCategoryNames() { return Collections.elements( categories.keySet() ); } /** * Get the names of all the items in one of the categories. * * @param categoryName - the <code>String</code> name of the category * whose item names are required. * @return an <code>Enumeration</code> of <code>String</code> names. * This value will not be <code>null</code>, but it may be empty. */ public Enumeration getItemNames( String categoryName ) { // Get the map with the given category name. TreeMap items = (TreeMap) categories.get( categoryName ); // Return the names of this category's items. return Collections.elements( items.keySet() ); } /** * Get the indicated item from the correct catagory. * * @param categoryName - the <code>String</code> name of the category * whose item names are required. * @param itemName - the <code>String</code> name of the indicated item. * @return the <code>Object<code> in the correct category with the given * name. This value may be <code>null</code>. * @throws <code>Exception</code> if there's any error getting the item. */ public Object getItem( String categoryName, String itemName ) throws Exception { // Get the map with the given category name. TreeMap items = (TreeMap) categories.get( categoryName ); // Make sure the category contains an item by that name. if ( !items.containsKey( itemName ) ) { return null; } // Find the named entry. ItemFile entry = (ItemFile) items.get( itemName ); // Return the item. return entry.getItem(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -