001/*
002  Copyright 2010-2016 Boxfuse GmbH
003  <p/>
004  Licensed under the Apache License, Version 2.0 (the "License");
005  you may not use this file except in compliance with the License.
006  You may obtain a copy of the License at
007  <p/>
008  http://www.apache.org/licenses/LICENSE-2.0
009  <p/>
010  Unless required by applicable law or agreed to in writing, software
011  distributed under the License is distributed on an "AS IS" BASIS,
012  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  See the License for the specific language governing permissions and
014  limitations under the License.
015 */
016package io.avaje.classpath.scanner.core;
017
018
019/**
020 * A starting location to scan from.
021 */
022public final class Location implements Comparable<Location> {
023
024  /**
025   * The prefix for classpath locations.
026   */
027  private static final String CLASSPATH_PREFIX = "classpath:";
028
029  /**
030   * The prefix for filesystem locations.
031   */
032  private static final String FILESYSTEM_PREFIX = "filesystem:";
033
034  /**
035   * The prefix part of the location. Can be either classpath: or filesystem:.
036   */
037  private final String prefix;
038
039  /**
040   * The path part of the location.
041   */
042  private String path;
043
044  /**
045   * Creates a new location.
046   *
047   * @param descriptor The location descriptor.
048   */
049  public Location(String descriptor) {
050
051    String normalizedDescriptor = descriptor.trim().replace("\\", "/");
052
053    if (normalizedDescriptor.contains(":")) {
054      prefix = normalizedDescriptor.substring(0, normalizedDescriptor.indexOf(":") + 1);
055      path = normalizedDescriptor.substring(normalizedDescriptor.indexOf(":") + 1);
056    } else {
057      prefix = CLASSPATH_PREFIX;
058      path = normalizedDescriptor;
059    }
060
061    if (isClassPath()) {
062      path = path.replace(".", "/");
063      if (path.startsWith("/")) {
064        path = path.substring(1);
065      }
066    } else {
067      if (!isFileSystem()) {
068        throw new ClassPathScanException("Unknown prefix, should be either filesystem: or classpath: " + normalizedDescriptor);
069      }
070    }
071
072    if (path.endsWith("/")) {
073      path = path.substring(0, path.length() - 1);
074    }
075  }
076
077  /**
078   * Return true if this denotes a classpath location.
079   */
080  public boolean isClassPath() {
081    return CLASSPATH_PREFIX.equals(prefix);
082  }
083
084  /**
085   * Return true if this denotes a filesystem location.
086   */
087  public boolean isFileSystem() {
088    return FILESYSTEM_PREFIX.equals(prefix);
089  }
090
091  /**
092   * Return the path part of the location.
093   */
094  public String getPath() {
095    return path;
096  }
097
098  /**
099   * Return the prefix denoting classpath of filesystem.
100   */
101  public String getPrefix() {
102    return prefix;
103  }
104
105  /**
106   * Return the complete location descriptor.
107   */
108  public String getDescriptor() {
109    return prefix + path;
110  }
111
112  public int compareTo(Location o) {
113    return getDescriptor().compareTo(o.getDescriptor());
114  }
115
116  @Override
117  public boolean equals(Object o) {
118    if (this == o) return true;
119    if (o == null || getClass() != o.getClass()) return false;
120
121    Location location = (Location) o;
122    return getDescriptor().equals(location.getDescriptor());
123  }
124
125  @Override
126  public int hashCode() {
127    return getDescriptor().hashCode();
128  }
129
130  @Override
131  public String toString() {
132    return getDescriptor();
133  }
134}