blob: 2553a5c7ff46d0f706898a39536707ea2970b781 [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.jena.riot.system.stream ;
import java.util.ArrayList ;
import java.util.Collections ;
import java.util.List ;
import org.apache.jena.atlas.lib.Lib;
import org.apache.jena.atlas.web.TypedInputStream ;
import org.apache.jena.riot.RiotNotFoundException ;
import org.apache.jena.riot.SysRIOT;
import org.apache.jena.sparql.util.Context;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
/**
* Management of stream opening, including redirecting through a location mapper
* whereby a name (e.g. URL) is redirected to another name (e.g. local file).
* Includes filename to IRI, handling ".gz" and "-"
*/
public class StreamManager {
private static Logger log = LoggerFactory.getLogger(StreamManager.class) ;
public static boolean logAllLookups = true ;
private List<Locator> handlers = new ArrayList<>() ;
private LocationMapper mapper = null ;
private static StreamManager globalStreamManager ;
/**
* Return a default configuration StreamManager with a {@link LocatorFile},
* {@link LocatorHTTP}, {@link LocatorFTP} and {@link LocatorClassLoader}
*/
public static StreamManager createStd() {
StreamManager streamManager = new StreamManager() ;
streamManager.addLocator(new LocatorFile()) ;
streamManager.addLocator(new LocatorHTTP()) ;
streamManager.addLocator(new LocatorFTP()) ;
streamManager.addLocator(new LocatorClassLoader(streamManager.getClass().getClassLoader())) ;
streamManager.setLocationMapper(JenaIOEnvironment.getLocationMapper()) ;
return streamManager ;
}
/** @deprecate Use {@link #createStd()} */
@Deprecated
public static StreamManager makeDefaultStreamManager() { return createStd() ; }
/**
* Return the global {@code StreamManager}.
*/
public static StreamManager get() {
return globalStreamManager ;
}
/**
* Return the {@code StreamManager} in a context, or the global one if the context is
* null or does not contain a valid entry for a {@code StreamManager}.
* <p>
* The {@code StreamManager} is keyed in the context by
* {@link SysRIOT#sysStreamManager}.
*/
public static StreamManager get(Context context) {
if ( context == null )
return get();
try {
if ( context.isDefined(SysRIOT.sysStreamManager))
return (StreamManager)context.get(SysRIOT.sysStreamManager);
}
catch (ClassCastException ex) {
log.warn("Context symbol '" + SysRIOT.sysStreamManager + "' is not a " + Lib.classShortName(StreamManager.class));
}
return get();
}
/**
* Set the global {@code StreamManager}.
*/
public static void setGlobal(StreamManager streamManager) {
globalStreamManager = streamManager ;
}
static { setGlobal(createStd()) ; }
/** Create a {@code StreamManager} with no locator or location mapper. */
public StreamManager() {}
/** Create a deep copy of this StreamManager */
@Override
public StreamManager clone() {
return clone(this) ;
}
private static StreamManager clone(StreamManager other) {
StreamManager sm = new StreamManager() ;
sm.handlers.addAll(other.handlers) ;
sm.mapper = other.mapper == null ? null : other.mapper.clone() ;
return sm ;
}
/**
* Open a file using the locators of this StreamManager.
* Returns null if not found.
*/
public TypedInputStream open(String filenameOrURI) {
if ( log.isDebugEnabled() )
log.debug("open(" + filenameOrURI + ")") ;
String uri = mapURI(filenameOrURI) ;
if ( log.isDebugEnabled() && !uri.equals(filenameOrURI) )
log.debug("open: mapped to " + uri) ;
return openNoMapOrNull(uri) ;
}
/** Apply the mapping of a filename or URI */
public String mapURI(String filenameOrURI) {
if ( mapper == null )
return filenameOrURI ;
String uri = mapper.altMapping(filenameOrURI, null) ;
if ( uri == null ) {
if ( StreamManager.logAllLookups && log.isDebugEnabled() )
log.debug("Not mapped: " + filenameOrURI) ;
uri = filenameOrURI ;
} else {
if ( log.isDebugEnabled() )
log.debug("Mapped: " + filenameOrURI + " => " + uri) ;
}
return uri ;
}
/**
* Open a file using the locators of this StreamManager but without location
* mapping. Throws RiotNotFoundException if not found.
*/
public TypedInputStream openNoMap(String filenameOrURI) {
TypedInputStream in = openNoMapOrNull(filenameOrURI) ;
if ( in == null )
throw new RiotNotFoundException(filenameOrURI) ;
return in ;
}
/**
* Open a file using the locators of this StreamManager without location
* mapping. Return null if not found
*/
public TypedInputStream openNoMapOrNull(String filenameOrURI) {
for (Locator loc : handlers) {
TypedInputStream in = loc.open(filenameOrURI) ;
if ( in != null ) {
if ( log.isDebugEnabled() )
log.debug("Found: " + filenameOrURI + " (" + loc.getName() + ")") ;
return in ;
}
}
return null ;
}
/** Set the location mapping */
public void setLocationMapper(LocationMapper _mapper) {
mapper = _mapper ;
}
/** Get the location mapping */
public LocationMapper getLocationMapper() {
return mapper ;
}
/** Return an immutable list of all the handlers */
public List<Locator> locators() {
return Collections.unmodifiableList(handlers) ;
}
/** Remove a locator. */
public void remove(Locator loc) {
handlers.remove(loc) ;
}
/** Remove all locators */
public void clearLocators() {
handlers.clear() ;
}
/**
* Add a locator to the end of the locators list.
* Returns {@code this} StreamManager.
*/
public StreamManager addLocator(Locator loc) {
handlers.add(loc) ;
return this;
}
}