| /*=============================================================================# |
| # Copyright (c) 2011, 2022 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.RJContext.RJ_PATH_SEPARATOR; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| |
| 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.jcommons.runtime.CommonsRuntime; |
| import org.eclipse.statet.jcommons.runtime.bundle.BundleEntry; |
| import org.eclipse.statet.jcommons.runtime.bundle.BundleSpec; |
| |
| import org.eclipse.statet.rj.data.RObject; |
| import org.eclipse.statet.rj.server.RjsStatus; |
| |
| |
| /** |
| * Server utilities. |
| */ |
| @NonNullByDefault |
| public class ServerUtils { |
| |
| |
| public static final String JCOMMONS_UTIL_ID= "org.eclipse.statet.jcommons.util"; //$NON-NLS-1$ |
| public static final BundleSpec JCOMMONS_UTIL_SPEC= new BundleSpec(JCOMMONS_UTIL_ID, CommonsRuntime.class); |
| |
| public static final String RJ_DATA_ID= "org.eclipse.statet.rj.data"; //$NON-NLS-1$ |
| public static final BundleSpec RJ_DATA_SPEC= new BundleSpec(RJ_DATA_ID, RObject.class); |
| public static final String RJ_SERVER_ID= "org.eclipse.statet.rj.server"; //$NON-NLS-1$ |
| public static final BundleSpec RJ_SERVER_SPEC= new BundleSpec(RJ_SERVER_ID, RJContext.class); |
| |
| public static final ImList<BundleSpec> MIN_CLASSPATH_SPECS= ImCollections.newList( |
| JCOMMONS_UTIL_SPEC, |
| RJ_DATA_SPEC, RJ_SERVER_SPEC ); |
| |
| public static final ImList<BundleSpec> MIN_RMI_CODEBASE_SPECS= ImCollections.newList( |
| RJ_SERVER_SPEC ); |
| |
| |
| public static final int[] RJ_VERSION= new int[] { 4, 0, 0 }; |
| |
| public static final RjsStatus MISSING_ANSWER_STATUS= new RjsStatus(RjsStatus.ERROR, 121, "Server error (missing answer)."); |
| |
| |
| public static class ArgKeyValue { |
| |
| private final String key; |
| private final @Nullable String value; |
| |
| public ArgKeyValue(final String key, final @Nullable String value) { |
| this.key= key; |
| this.value= value; |
| } |
| |
| |
| public String getKey() { |
| return this.key; |
| } |
| |
| public @Nullable String getValue() { |
| return this.value; |
| } |
| |
| } |
| |
| /** |
| * Split at next ':' |
| * @param arg the argument to split |
| * @return key value pair |
| */ |
| public static ArgKeyValue getArgSubValue(final @Nullable String arg) { |
| if (arg != null && arg.length() > 0) { |
| final int idx= arg.indexOf(':'); |
| if (idx >= 0) { |
| return new ArgKeyValue(arg.substring(0, idx), arg.substring(idx + 1)); |
| } |
| else { |
| return new ArgKeyValue(arg, null); |
| } |
| } |
| else { |
| return new ArgKeyValue("", null); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Split at next '=' |
| * @param arg the argument to split |
| * @return key value pair |
| */ |
| public static ArgKeyValue getArgConfigValue(final @Nullable String arg) { |
| if (arg != null && arg.length() > 0) { |
| final int idx= arg.indexOf('='); |
| if (idx >= 0) { |
| return new ArgKeyValue(arg.substring(0, idx), arg.substring(idx + 1)); |
| } |
| else { |
| return new ArgKeyValue(arg, null); |
| } |
| } |
| else { |
| return new ArgKeyValue("", null); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Split at ',' |
| * @param arg the argument to split |
| * @return List with String |
| */ |
| public static List<String> getArgValueList(final @Nullable String arg) { |
| if (arg != null && arg.length() > 0) { |
| return Arrays.asList(arg.split(",")); //$NON-NLS-1$ |
| } |
| else { |
| return Collections.emptyList(); |
| } |
| } |
| |
| public static void prettyPrint(final Map map, final StringBuilder sb) { |
| final String sep= System.lineSeparator() + "\t"; |
| final Set<Entry<?, ?>> entrySet= map.entrySet(); |
| for (final Entry<?, ?> entry : entrySet) { |
| sb.append(sep); |
| sb.append(entry.getKey()); |
| sb.append('='); |
| final Object value= entry.getValue(); |
| if (value != null) { |
| sb.append(value); |
| } |
| } |
| } |
| |
| public static void prettyPrint(final Collection<?> list, final StringBuilder sb) { |
| final String sep= System.lineSeparator() + "\t"; |
| for (final Object value : list) { |
| sb.append(sep); |
| if (value != null) { |
| sb.append(value); |
| } |
| } |
| } |
| |
| public static void prettyPrintVersion(final int[] version, final StringBuilder sb) { |
| if (version == null || version.length == 0) { |
| sb.append("<missing>"); |
| } |
| else { |
| sb.append(version[0]); |
| for (int i= 1; i < version.length; i++) { |
| sb.append('.'); |
| sb.append(version[i]); |
| } |
| } |
| } |
| |
| |
| public static String concatJClassPath(final Collection<BundleEntry> entries) { |
| if (entries.isEmpty()) { |
| return ""; |
| } |
| final List<String> uniqueStrings= new ArrayList<>(entries.size()); |
| final StringBuilder sb= new StringBuilder(); |
| for (final BundleEntry entry : entries) { |
| final String s= entry.getJClassPathString(); |
| if (!uniqueStrings.contains(s)) { |
| uniqueStrings.add(s); |
| sb.append(s); |
| sb.append(File.pathSeparatorChar); |
| } |
| } |
| return sb.substring(0, sb.length() - 1); |
| } |
| |
| public static String concatRJClassPath(final Collection<BundleEntry> entries) { |
| if (entries.isEmpty()) { |
| return ""; |
| } |
| final List<String> uniqueStrings= new ArrayList<>(entries.size()); |
| final StringBuilder sb= new StringBuilder(); |
| for (final BundleEntry entry : entries) { |
| final String s= entry.getJClassPathUrlString(); |
| if (!uniqueStrings.contains(s)) { |
| uniqueStrings.add(s); |
| sb.append(s); |
| sb.append(RJ_PATH_SEPARATOR); |
| } |
| } |
| return sb.substring(0, sb.length() - RJ_PATH_SEPARATOR.length()); |
| } |
| |
| /** |
| * Concats the specified entries to a valid codebase property value. |
| * The entries have to be path in the local file system. It is recommend to specify the entries |
| * as URL with the schema 'file'. |
| */ |
| public static String concatCodebase(final Collection<BundleEntry> entries) { |
| if (entries.isEmpty()) { |
| return ""; |
| } |
| final List<String> uniqueStrings= new ArrayList<>(entries.size()); |
| final StringBuilder sb= new StringBuilder(); |
| for (final BundleEntry entry : entries) { |
| final String s= entry.getJClassPath().toUri().toString(); |
| if (s != null && !uniqueStrings.contains(s)) { |
| sb.append(s); |
| sb.append(' '); |
| } |
| } |
| return sb.substring(0, sb.length()-1); |
| } |
| |
| } |