blob: 814f6aad7a9d5822310855b16abe067b058eaaf7 [file] [log] [blame]
/*
* 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.uima.fit.internal;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.uima.resource.ResourceInitializationException;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
/**
* INTERNAL API - Utility methods to locate and access uimaFIT meta data.
*/
public final class MetaDataUtil {
private MetaDataUtil() {
// No instances
}
/**
* Scan patterns from manifest files and from the specified system property.
*
* @param aType
* the type of metadata to scan for
* @return array or all patterns found.
* @throws ResourceInitializationException
* if there was a problem resolving the metadata locations from the patterns
*/
public static String[] scanImportsAndManifests(MetaDataType aType)
throws ResourceInitializationException {
ArrayList<String> patterns = new ArrayList<>();
// Scan auto-import locations
for (String property : getImportProperties(aType)) {
patterns.addAll(Arrays.asList(System.getProperty(property, "").split(";")));
}
// Scan manifest
for (String mfUrl : resolve(getManifestLocations(aType))) {
InputStream is = null;
try {
is = new URL(mfUrl).openStream();
List<? extends String> lines = IOUtils.readLines(is);
patterns.addAll(lines);
} catch (IOException e) {
throw new ResourceInitializationException(e);
} finally {
IOUtils.closeQuietly(is);
}
}
return patterns.toArray(new String[patterns.size()]);
}
/**
* Resolve a list of patterns to a set of URLs.
*
* @param patterns
* the patterns to resolve
* @return an array of locations.
* @throws ResourceInitializationException
* if the locations could not be resolved.
*/
public static String[] resolve(String... patterns) throws ResourceInitializationException {
Set<String> locations = new HashSet<>();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
// Scan auto-import locations. Using a set to avoid scanning a pattern twice.
for (String pattern : new TreeSet<>(Arrays.asList(patterns))) {
String p = pattern.trim();
if (p.length() == 0) {
continue;
}
for (Resource r : resolver.getResources(pattern)) {
locations.add(r.getURL().toString());
}
}
return locations.toArray(new String[locations.size()]);
} catch (IOException e) {
throw new ResourceInitializationException(e);
}
}
/**
* Get manifest locations for the specified type.
*
* @param aType
* the type of metadata to scan for
* @return the manifest locations for this kind of metadata to scan
*/
public static String[] getManifestLocations(MetaDataType aType) {
List<String> locations = new ArrayList<>();
switch (aType) {
case FS_INDEX:
locations.add("classpath*:META-INF/org.apache.uima.fit/fsindexes.txt");
break;
case TYPE_SYSTEM:
locations.add("classpath*:META-INF/org.apache.uima.fit/types.txt");
break;
case TYPE_PRIORITIES:
locations.add("classpath*:META-INF/org.apache.uima.fit/typepriorities.txt");
break;
}
return locations.toArray(new String[locations.size()]);
}
/**
* Get system properties indicating which locations to scan for descriptions of the given type. A
* list of locations may be given separated by ";".
*
* @param aType
* the type of metadata to scan for
* @return the locations for this kind of metadata to scan
*/
public static String[] getImportProperties(MetaDataType aType) {
List<String> locations = new ArrayList<>();
switch (aType) {
case FS_INDEX:
locations.add("org.apache.uima.fit.fsindex.import_pattern");
break;
case TYPE_SYSTEM:
locations.add("org.apache.uima.fit.type.import_pattern");
break;
case TYPE_PRIORITIES:
locations.add("org.apache.uima.fit.typepriorities.import_pattern");
break;
}
return locations.toArray(new String[locations.size()]);
}
/**
* Get all currently accessible descriptor locations for the given type.
*
* @param aType
* the type of metadata to scan for
* @return an array of locations.
* @throws ResourceInitializationException
* if the locations could not be resolved.
*/
public static String[] scanDescriptors(MetaDataType aType)
throws ResourceInitializationException {
String[] locations1 = resolve(scanImportsAndManifests(aType));
String[] locations2 = LegacySupport.getInstance().scanTypeDescriptors(aType);
return (String[]) ArrayUtils.addAll(locations1, locations2);
}
}