blob: 7d5af866ec1e4c47373d961880fbce94a4c0c233 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2013, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.rj.server.util;
import static org.eclipse.statet.rj.server.util.ServerUtils.RJ_SERVER_ID;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.rj.RjInitFailedException;
import org.eclipse.statet.rj.RjInvalidConfigurationException;
@NonNullByDefault
public class RJContext {
public static final String RJ_BUNDLE_PATH_PROPERTY_KEY= "org.eclipse.statet.rj.Path"; //$NON-NLS-1$
public static final String RJ_SERVER_CLASS_PATH_PROPERTY_KEY= "org.eclipse.statet.rj.server.ClassPath.urls"; //$NON-NLS-1$
public static final String RJ_PATH_SEPARATOR= ":,:"; //$NON-NLS-1$
private static final Pattern RJ_PATH_SEPARATOR_PATTERN= Pattern.compile(RJ_PATH_SEPARATOR, Pattern.LITERAL);
protected static final String LOCALHOST_POLICY_FILENAME= "localhost.policy"; //$NON-NLS-1$
public static PathEntryProvider detectRJLibPaths() throws RjInitFailedException {
List<Path> expliciteBaseDirectories= null;
final String path= System.getProperty(RJ_BUNDLE_PATH_PROPERTY_KEY);
if (path != null) {
expliciteBaseDirectories= new ArrayList<>();
final String[] directories= RJ_PATH_SEPARATOR_PATTERN.split(path);
for (final String pathString : directories) {
expliciteBaseDirectories.add(Paths.get(pathString));
}
}
return PathEntryProvider.detectLibPaths(RJContext.class, expliciteBaseDirectories);
}
private ImList<PathEntryProvider> libPathEntryProviders;
public RJContext(final PathEntryProvider pathEntryProvider,
final PathEntryProvider ... pathEntryProviderAdditionals) {
this.libPathEntryProviders= ImCollections.addElement(
ImCollections.newList(pathEntryProviderAdditionals),
0, pathEntryProvider);
}
protected RJContext() {
}
public List<PathEntry> searchRJLibs(final List<String> libIds)
throws RjInvalidConfigurationException {
final List<? extends PathEntry> candidates= getRJLibCandidates();
final ArrayList<PathEntry> resolved= new ArrayList<>(libIds.size());
StringBuilder sb= null;
Collections.sort(candidates);
for (final String libId : libIds) {
final PathEntry entry= searchLib(candidates, libId);
if (entry == null) {
if (sb == null) {
sb= new StringBuilder("Missing RJ library ");
}
else {
sb.append(", "); //$NON-NLS-1$
}
sb.append('\'');
sb.append(libId);
sb.append('\'');
}
else {
resolved.add(entry);
}
}
if (sb != null) {
sb.append('.');
throw new RjInvalidConfigurationException(sb.toString());
}
return resolved;
}
protected List<? extends PathEntry> getRJLibCandidates() throws RjInvalidConfigurationException {
final List<PathEntry> pathsEntries= new ArrayList<>();
for (final PathEntryProvider provider : this.libPathEntryProviders) {
provider.getEntries(pathsEntries);
}
return pathsEntries;
}
protected @Nullable PathEntry searchLib(final List<? extends PathEntry> files, final String bundleId) {
for (final PathEntry entry : files) {
if (entry.bundleId.equals(bundleId)) {
return entry;
}
}
return null;
}
public String getServerPolicyFilePath() throws RjInvalidConfigurationException {
final URL resource= RJContext.class.getClassLoader().getResource(LOCALHOST_POLICY_FILENAME);
if (resource != null) {
resource.toString();
}
try {
final PathEntry lib= searchRJLibs(ImCollections.newList(RJ_SERVER_ID)).get(0);
final Path policyPath= lib.getResourcePath(LOCALHOST_POLICY_FILENAME);
if (policyPath != null && Files.isRegularFile(policyPath)) {
return policyPath.toUri().toString();
}
else {
final String s= lib.getUrlString();
if (s.endsWith("/")) { //$NON-NLS-1$
return s + LOCALHOST_POLICY_FILENAME;
}
}
throw new UnsupportedOperationException(String.format("PathEntry= '%1$s'", lib));
}
catch (final Exception e) {
throw new RjInvalidConfigurationException("Failed find server policy file.", e);
}
}
protected String getPropertiesDirPath() {
return System.getProperty("user.dir");
}
protected @Nullable InputStream getInputStream(final String path) throws IOException {
final File file= new File(path);
if (!file.exists()) {
return null;
}
return new FileInputStream(file);
}
protected OutputStream getOutputStream(final String path) throws IOException {
final File file= new File(path);
return new FileOutputStream(file, false);
}
public @Nullable Properties loadProperties(final String name) throws IOException {
if (name == null) {
throw new NullPointerException("name");
}
final String path= getPropertiesDirPath() + '/' + name + ".properties"; //$NON-NLS-1$
final InputStream in= getInputStream(path);
if (in == null) {
return null;
}
final Properties properties= new Properties();
try {
properties.load(in);
}
finally {
if (in != null) {
try {
in.close();
}
catch (final IOException e) {}
}
}
return properties;
}
public void saveProperties(final String name, final Properties properties) throws IOException {
if (name == null) {
throw new NullPointerException("name");
}
if (properties == null) {
throw new NullPointerException("properties");
}
final String path= getPropertiesDirPath() + '/' + name + ".properties"; //$NON-NLS-1$
final OutputStream out= getOutputStream(path);
try {
properties.store(out, null);
}
finally {
if (out != null) {
try {
out.close();
}
catch (final IOException e) {}
}
}
}
}