| /********************************************************************** |
| * Copyright (c) 2002, 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| **********************************************************************/ |
| |
| package org.eclipse.wtp.releng.tools.component.internal; |
| |
| import java.io.File; |
| import org.eclipse.wtp.releng.tools.component.ILocation; |
| import org.eclipse.wtp.releng.tools.component.ILocationChildrenIterator; |
| import org.eclipse.wtp.releng.tools.component.ILocationVisitor; |
| |
| /** |
| * The <code>Location</code> class is a concrete implementation of the |
| * <code>ILocation</code> interface. It provides a static convienience method |
| * for creating new <code>Location</code> objects. |
| * <p> |
| * Note that all locations use '/' as their file separator. |
| */ |
| public abstract class Location implements ILocation |
| { |
| protected ILocation parent; |
| protected String name; |
| |
| /** |
| * Creates a new <code>Location</code> with the given parent and the given |
| * name |
| * |
| * @param parent |
| * The parent location, can be <code>null</code> |
| * @param fullName |
| * The name of this location, cannot be <code>null</code> s |
| */ |
| public Location(ILocation parent, String fullName) |
| { |
| this.parent = parent; |
| this.name = fullName.replace('\\', '/'); |
| } |
| |
| /* |
| * @see com.example.location.ILocation#accept(com.example.location.ILocationVisitor) |
| */ |
| public void accept(ILocationVisitor visitor) |
| { |
| if (visitor.accept(this)) |
| { |
| if (hasChildren()) |
| { |
| ILocationChildrenIterator i = childIterator(); |
| ILocation child = i.next(); |
| while (child != null) |
| { |
| child.accept(visitor); |
| child = i.next(); |
| } |
| } |
| } |
| } |
| |
| /* |
| * @see com.example.location.ILocation#getParent() |
| */ |
| public ILocation getParent() |
| { |
| return parent; |
| } |
| |
| /* |
| * @see com.example.location.ILocation#getName() |
| */ |
| public String getName() |
| { |
| return name; |
| } |
| |
| /** |
| * Creates a new location from a file. Clients can create locations on |
| * directories or archive files (jar, zip, war, ear). |
| * |
| * @param file |
| * The file to wrap, not <code>null</code> |
| * @return ILocation The resulting location, can be <code>null</code> if the |
| * file does not exist, is not a directory, or is not an archive. |
| */ |
| public static ILocation createLocation(File file) |
| { |
| if (!file.exists()) |
| { |
| return null; |
| } |
| if (file.isDirectory()) |
| { |
| return new FileLocation(file); |
| } |
| if (isArchive(file.getAbsolutePath())) |
| { |
| return new ZipLocation(file); |
| } |
| return null; |
| } |
| |
| /** |
| * Answers <code>true</code> if the path ends in ".jar", ".zip", ".ear", or |
| * ".war". |
| * <p> |
| * This code has been optimized to within an inch of its life. |
| * |
| * @param path |
| * The path of the file |
| * @return boolean <code>true</code> if the path represents a jar, zip, ear, |
| * or war file. |
| */ |
| public static boolean isArchive(String path) |
| { |
| if (path == null) |
| return false; |
| if (path.length() < 5) |
| return false; |
| int index = path.length() - 1; |
| char extChar = path.charAt(index--); |
| switch (extChar) |
| { |
| case 'p' : |
| case 'P' : |
| if (path.endsWith(".zip")) |
| { |
| return true; |
| } |
| break; |
| case 'r' : |
| case 'R' : |
| extChar = path.charAt(index--); |
| switch (extChar) |
| { |
| case 'a' : |
| case 'A' : |
| extChar = path.charAt(index--); |
| switch (extChar) |
| { |
| case 'j' : |
| case 'J' : |
| if (path.charAt(index) == '.') |
| { |
| return true; |
| } |
| break; |
| case 'w' : |
| case 'W' : |
| if (path.charAt(index) == '.') |
| { |
| return true; |
| } |
| break; |
| case 'e' : |
| case 'E' : |
| if (path.charAt(index) == '.') |
| { |
| return true; |
| } |
| break; |
| } |
| } |
| break; |
| } |
| return false; |
| } |
| |
| /** |
| * Answers the extension of the given path. An extension is normally a three |
| * character addition to the end of a filename separated from the filename by |
| * the '.' character. |
| * |
| * @param path |
| * a file path, not <code>null</code> |
| * @return String the extension of the path |
| */ |
| public static String getExtension(String path) |
| { |
| int index = path.lastIndexOf('.'); |
| if (index < 0) |
| return ""; |
| return path.substring(index + 1).toLowerCase(); |
| } |
| |
| /* |
| * @see java.lang.Object#equals(java.lang.Object) |
| */ |
| public boolean equals(Object object) |
| { |
| if (object == null) |
| { |
| return false; |
| } |
| if (object == this) |
| { |
| return true; |
| } |
| if (object instanceof ILocation) |
| { |
| ILocation location = this; |
| ILocation otherLocation = (ILocation)object; |
| do |
| { |
| if (!location.getName().equals(otherLocation.getName())) |
| { |
| return false; |
| } |
| location = location.getParent(); |
| otherLocation = otherLocation.getParent(); |
| } |
| while (location != null && otherLocation != null); |
| if (location == null) |
| { |
| if (otherLocation == null) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| else |
| { |
| if (otherLocation == null) |
| { |
| return false; |
| } |
| else |
| { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| /* |
| * @see java.lang.Object#hashCode() |
| */ |
| public int hashCode() |
| { |
| StringBuffer b = new StringBuffer(); |
| ILocation location = this; |
| while (location != null) |
| { |
| b.insert(0, getName()); |
| location = location.getParent(); |
| } |
| return b.toString().hashCode(); |
| } |
| } |