/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.cxf.common.util; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import org.apache.cxf.helpers.JavaUtils; public final class PackageUtils { private PackageUtils() { } static String getPackageName(String className) { int pos = className.lastIndexOf('.'); if (pos != -1) { return className.substring(0, pos); } else { return ""; } } public static String getPackageName(Class<?> clazz) { String className = clazz.getName(); if (className.startsWith("[L")) { className = className.substring(2); } return getPackageName(className); } public static String getSharedPackageName(List<Class<?>> classes) { if (classes.isEmpty()) { return ""; } List<List<String>> lParts = new ArrayList<List<String>>(classes.size()); List<String> currentParts = new ArrayList<>(); for (Class<?> cls : classes) { if (!Proxy.isProxyClass(cls)) { lParts.add(StringUtils.getParts(getPackageName(cls), "\\.")); } } for (int i = 0; i < lParts.get(0).size(); i++) { int j = 1; for (; j < lParts.size(); j++) { if (i > (lParts.get(j).size() - 1) || !lParts.get(j).get(i).equals(lParts.get(0).get(i))) { break; } } if (j == lParts.size()) { currentParts.add(lParts.get(j - 1).get(i)); } else { break; } } StringBuilder sb = new StringBuilder(); for (String part : currentParts) { if (sb.length() > 0) { sb.append("."); } sb.append(part); } return sb.toString(); } public static String parsePackageName(String namespace, String defaultPackageName) { String packageName = (defaultPackageName != null && defaultPackageName.trim().length() > 0) ? defaultPackageName : null; if (packageName == null) { packageName = getPackageNameByNameSpaceURI(namespace); } return packageName; } public static String getPackageNameByNameSpaceURI(String nameSpaceURI) { int idx = nameSpaceURI.indexOf(':'); String scheme = ""; if (idx >= 0) { scheme = nameSpaceURI.substring(0, idx); if ("http".equalsIgnoreCase(scheme) || "urn".equalsIgnoreCase(scheme)) { nameSpaceURI = nameSpaceURI.substring(idx + 1); } } List<String> tokens = tokenize(nameSpaceURI, "/: "); if (tokens.size() == 0) { return null; } if (tokens.size() > 1) { String lastToken = tokens.get(tokens.size() - 1); idx = lastToken.lastIndexOf('.'); if (idx > 0) { lastToken = lastToken.substring(0, idx); tokens.set(tokens.size() - 1, lastToken); } } String domain = tokens.get(0); idx = domain.indexOf(':'); if (idx >= 0) { domain = domain.substring(0, idx); } List<String> r = reverse(tokenize(domain, "urn".equals(scheme) ? ".-" : ".")); if ("www".equalsIgnoreCase(r.get(r.size() - 1))) { // remove leading www r.remove(r.size() - 1); } // replace the domain name with tokenized items tokens.addAll(1, r); tokens.remove(0); // iterate through the tokens and apply xml->java name algorithm for (int i = 0; i < tokens.size(); i++) { // get the token and remove illegal chars String token = tokens.get(i); token = removeIllegalIdentifierChars(token); // this will check for reserved keywords if (containsReservedKeywords(token)) { token = '_' + token; } tokens.set(i, token.toLowerCase()); } // concat all the pieces and return it return combine(tokens, '.'); } private static List<String> tokenize(String str, String sep) { StringTokenizer tokens = new StringTokenizer(str, sep); List<String> r = new ArrayList<>(); while (tokens.hasMoreTokens()) { r.add(tokens.nextToken()); } return r; } private static <T> List<T> reverse(List<T> a) { List<T> r = new ArrayList<>(); for (int i = a.size() - 1; i >= 0; i--) { r.add(a.get(i)); } return r; } private static String removeIllegalIdentifierChars(String token) { StringBuilder newToken = new StringBuilder(); for (int i = 0; i < token.length(); i++) { char c = token.charAt(i); if (i == 0 && !Character.isJavaIdentifierStart(c)) { // prefix an '_' if the first char is illegal newToken.append("_" + c); } else if (!Character.isJavaIdentifierPart(c)) { // replace the char with an '_' if it is illegal newToken.append('_'); } else { // add the legal char newToken.append(c); } } return newToken.toString(); } private static String combine(List<?> r, char sep) { StringBuilder buf = new StringBuilder(r.get(0).toString()); for (int i = 1; i < r.size(); i++) { buf.append(sep); buf.append(r.get(i)); } return buf.toString(); } private static boolean containsReservedKeywords(String token) { return JavaUtils.isJavaKeyword(token); } public static String getNamespace(String packageName) { if (packageName == null || packageName.length() == 0) { return null; } StringTokenizer tokenizer = new StringTokenizer(packageName, "."); String[] tokens; if (tokenizer.countTokens() == 0) { tokens = new String[0]; } else { tokens = new String[tokenizer.countTokens()]; for (int i = tokenizer.countTokens() - 1; i >= 0; i--) { tokens[i] = tokenizer.nextToken(); } } StringBuilder namespace = new StringBuilder("http://"); String dot = ""; for (int i = 0; i < tokens.length; i++) { if (i == 1) { dot = "."; } namespace.append(dot + tokens[i]); } namespace.append('/'); return namespace.toString(); } }