/**
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.examples.marketdata;
import java.io.File;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableSet;
import com.opengamma.strata.collect.Messages;
import com.opengamma.strata.collect.io.ResourceLocator;
/**
* Loads market data from the standard directory structure embedded within a JAR file.
*/
public class JarMarketDataBuilder extends ExampleMarketDataBuilder {
/**
* The JAR file containing the expected structure of resources.
*/
private final File jarFile;
/**
* The root path to the resources within the JAR file.
*/
private final String rootPath;
/**
* A cache of JAR entries under the root path.
*/
private final ImmutableSet<String> entries;
/**
* Constructs an instance.
*
* @param jarFile the JAR file containing the expected structure of resources
* @param rootPath the root path to the resources within the JAR file
*/
public JarMarketDataBuilder(File jarFile, String rootPath) {
// classpath resources are forward-slash separated
String jarRoot = rootPath.startsWith("/") ? rootPath.substring(1) : rootPath;
if (!jarRoot.endsWith("/")) {
jarRoot += "/";
}
this.jarFile = jarFile;
this.rootPath = jarRoot;
this.entries = getEntries(jarFile, rootPath);
}
//-------------------------------------------------------------------------
@Override
protected Collection<ResourceLocator> getAllResources(String subdirectoryName) {
String resolvedSubdirectory = subdirectoryName + "/";
return entries.stream()
.filter(e -> e.startsWith(resolvedSubdirectory) && !e.equals(resolvedSubdirectory))
.map(e -> getEntryLocator(rootPath + e))
.collect(Collectors.toSet());
}
@Override
protected ResourceLocator getResource(String subdirectoryName, String resourceName) {
String fullLocation = String.format(Locale.ENGLISH, "%s%s/%s", rootPath, subdirectoryName, resourceName);
try (JarFile jar = new JarFile(jarFile)) {
JarEntry entry = jar.getJarEntry(fullLocation);
if (entry == null) {
return null;
}
return getEntryLocator(entry.getName());
} catch (Exception e) {
throw new IllegalArgumentException(
Messages.format("Error loading resource from JAR file: {}", jarFile), e);
}
}
@Override
protected boolean subdirectoryExists(String subdirectoryName) {
// classpath resources are forward-slash separated
String resolvedName = subdirectoryName.startsWith("/") ? subdirectoryName.substring(1) : subdirectoryName;
if (!resolvedName.endsWith("/")) {
resolvedName += "/";
}
return entries.contains(resolvedName);
}
//-------------------------------------------------------------------------
// Gets the resource locator corresponding to a given entry
private ResourceLocator getEntryLocator(String entryName) {
return ResourceLocator.ofClasspath(entryName);
}
private static ImmutableSet<String> getEntries(File jarFile, String rootPath) {
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
try (JarFile jar = new JarFile(jarFile)) {
Enumeration<JarEntry> jarEntries = jar.entries();
while (jarEntries.hasMoreElements()) {
JarEntry entry = jarEntries.nextElement();
String entryName = entry.getName();
if (entryName.startsWith(rootPath) && !entryName.equals(rootPath)) {
String relativeEntryPath = entryName.substring(rootPath.length() + 1);
if (!relativeEntryPath.trim().isEmpty()) {
builder.add(relativeEntryPath);
}
}
}
} catch (Exception e) {
throw new IllegalArgumentException(
Messages.format("Error scanning entries in JAR file: {}", jarFile), e);
}
return builder.build();
}
}