001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.wicket.util.lang; 018 019import org.apache.wicket.util.string.StringList; 020 021/** 022 * Utilities for dealing with packages. 023 * 024 * @author Jonathan Locke 025 * @author Niclas Hedhman 026 */ 027public final class Packages 028{ 029 /** 030 * Takes a package and a path to a resource and returns an absolute path to the resource. 031 * <p> 032 * See {@link #absolutePath(String, String)} for details. 033 * 034 * @param p 035 * The package to start at 036 * @param path 037 * The path to the resource 038 * @return The absolute path 039 */ 040 public static String absolutePath(final Class<?> p, final String path) 041 { 042 String packName = (p != null ? extractPackageName(p) : ""); 043 return absolutePath(packName, path); 044 } 045 046 /** 047 * Takes a package and a path to a resource and returns an absolute path to the resource. 048 * <p> 049 * See {@link #absolutePath(String, String)} for details. 050 * 051 * @param p 052 * The package to start at 053 * @param relativePath 054 * The path to the resource 055 * @return The absolute path 056 */ 057 public static String absolutePath(final Package p, final String relativePath) 058 { 059 return absolutePath(p.getName(), relativePath); 060 } 061 062 /** 063 * Takes a package and a path to a resource and returns an absolute path to the resource. For 064 * example, if the given package was java.lang and the relative path was "../util/List", then 065 * "java/util/List" would be returned. An already absolute path stays absolute. 066 * <p> 067 * Note: The returned absolute path does not start with a slash ("/"). 068 * 069 * @param packageName 070 * The package to start at 071 * @param path 072 * The path to the resource 073 * @return The absolute path 074 */ 075 public static String absolutePath(final String packageName, final String path) 076 { 077 // Is path already absolute? 078 if (path.startsWith("/")) 079 { 080 return path.substring(1); 081 } 082 else 083 { 084 // Break package into list of package names 085 final StringList absolutePath = StringList.tokenize(packageName, "."); 086 087 // Break path into folders 088 final StringList folders = StringList.tokenize(path, "/\\"); 089 090 // Iterate through folders 091 for (int i = 0, size = folders.size(); i < size; i++) 092 { 093 // Get next folder 094 final String folder = folders.get(i); 095 096 // Up one? 097 if ("..".equals(folder)) 098 { 099 // Pop off stack 100 if (absolutePath.size() > 0) 101 { 102 absolutePath.removeLast(); 103 } 104 else 105 { 106 throw new IllegalArgumentException("Invalid path " + path); 107 } 108 } 109 else if (".".equals(folder) == false) 110 { 111 // Add to stack 112 absolutePath.add(folder); 113 } 114 } 115 116 // Return absolute path 117 return absolutePath.join("/"); 118 } 119 } 120 121 /** 122 * Determines the package name for the given class. 123 * 124 * @param forClass 125 * the class 126 * @return the package name 127 */ 128 public static String extractPackageName(final Class<?> forClass) 129 { 130 return parent(forClass.getName()); 131 } 132 133 /** 134 * Gets the parent package name. 135 * 136 * @param packageName 137 * The Package name 138 * @return The parent Package 139 */ 140 public static String parent(final String packageName) 141 { 142 int pos = packageName.lastIndexOf("."); 143 String parent; 144 if (pos < 0) 145 { 146 pos = packageName.lastIndexOf("/"); 147 if (pos < 0) 148 { 149 pos = 0; 150 } 151 } 152 parent = packageName.substring(0, pos); 153 return parent; 154 } 155 156 157 /** 158 * Resolve scope for the given class by extracting it's package name and converting all dots to 159 * slashes. 160 * 161 * @param forClass 162 * the class 163 * @return the scope string 164 */ 165 public static String resolveScope(final Class<?> forClass) 166 { 167 String packName = extractPackageName(forClass); 168 return packName.replace('.', '/'); 169 } 170 171 /** 172 * Instantiation not allowed. 173 */ 174 private Packages() 175 { 176 } 177}