ModelUris.java
package org.jmad.modelpack.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.isNullOrEmpty;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toMap;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.NoSuchElementException;
import cern.accsoft.steering.jmad.domain.machine.RangeDefinition;
import cern.accsoft.steering.jmad.domain.machine.SequenceDefinition;
import cern.accsoft.steering.jmad.model.JMadModel;
import cern.accsoft.steering.jmad.model.JMadModelStartupConfiguration;
import cern.accsoft.steering.jmad.modeldefs.domain.JMadModelDefinition;
import cern.accsoft.steering.jmad.modeldefs.domain.OpticsDefinition;
public final class ModelUris {
private static final String SEQUENCE_URI_PARAMETER = "seq";
private static final String OPTIC_URI_PARAMETER = "optic";
private ModelUris() {
throw new UnsupportedOperationException("static only");
}
public static URI modelUri(JMadModel model) {
RangeDefinition rangeDefinition = model.getActiveRangeDefinition();
OpticsDefinition opticsDefinition = model.getActiveOpticsDefinition();
JMadModelStartupConfiguration startupConfiguration = new JMadModelStartupConfiguration();
startupConfiguration.setLoadDefaultRange(false);
startupConfiguration.setInitialOpticsDefinition(opticsDefinition);
startupConfiguration.setInitialRangeDefinition(rangeDefinition);
return modelDefinitionUri(model.getModelDefinition(), startupConfiguration);
}
public static URI modelDefinitionUri(JMadModelDefinition modelDefinition,
JMadModelStartupConfiguration startupConfiguration) {
requireNonNull(modelDefinition, "model definition must not be null");
String modelPackUri = modelDefinition.getModelPackUri();
checkState(modelPackUri != null,
"model pack URI of model definition [" + modelDefinition.getName() + "] is not set. "
+ "Perhaps this model definition was not load from a model pack?");
URI baseUri = URI.create(modelPackUri);
String localPart = buildUriLocalPart(modelDefinition.getName(), startupConfiguration);
try {
return new URI(baseUri.getScheme(), baseUri.getAuthority(), baseUri.getPath(), baseUri.getQuery(),
localPart);
} catch (URISyntaxException e) {
throw new IllegalStateException("Error building Model Pack URI", e);
}
}
public static URI modelDefinitionUri(JMadModelDefinition modelDefinition) {
return modelDefinitionUri(modelDefinition, null);
}
private static String buildUriLocalPart(String modelName, JMadModelStartupConfiguration startupConfiguration) {
String localPart = encodeUriComponent(modelName);
if (startupConfiguration == null) {
return localPart;
}
RangeDefinition initialRangeDefinition = startupConfiguration.getInitialRangeDefinition();
if (initialRangeDefinition != null) {
localPart += uriParameter(SEQUENCE_URI_PARAMETER) + encodeUriComponent(
initialRangeDefinition.getSequenceDefinition().getName());
}
OpticsDefinition opticsDefinition = startupConfiguration.getInitialOpticsDefinition();
if (opticsDefinition != null) {
localPart += uriParameter(OPTIC_URI_PARAMETER) + encodeUriComponent(opticsDefinition.getName());
}
return localPart;
}
private static String uriParameter(String parameterId) {
return "&" + parameterId + "=";
}
public static JMadModelStartupConfiguration startupConfigurationFromUri(URI uri,
JMadModelDefinition modelDefinition) {
String localPart = uri.getFragment();
checkArgument(!isNullOrEmpty(localPart), "No model information in URI");
Map<String, String> attributes = Arrays.stream(localPart.split("&")) //
.map(ModelUris::decodeUriComponent) //
.skip(1).map(s -> s.split("=")) //
.collect(toMap(s -> s[0], s -> s[1]));
JMadModelStartupConfiguration startupConfiguration = new JMadModelStartupConfiguration();
if (attributes.containsKey(SEQUENCE_URI_PARAMETER)) {
startupConfiguration.setLoadDefaultRange(false);
String sequenceName = attributes.get(SEQUENCE_URI_PARAMETER);
SequenceDefinition sequenceDefinition = modelDefinition.getSequenceDefinition(sequenceName);
if (sequenceDefinition == null) {
throw new NoSuchElementException(
"No sequence '" + sequenceName + "' defined in model " + modelDefinition.getName());
}
startupConfiguration.setInitialRangeDefinition(sequenceDefinition.getDefaultRangeDefinition());
}
if (attributes.containsKey(OPTIC_URI_PARAMETER)) {
String opticName = attributes.get(OPTIC_URI_PARAMETER);
OpticsDefinition opticsDefinition = modelDefinition.getOpticsDefinition(opticName);
if (opticsDefinition == null) {
throw new NoSuchElementException(
"No optic '" + opticName + "' defined in model " + modelDefinition.getName());
}
startupConfiguration.setInitialOpticsDefinition(opticsDefinition);
}
return startupConfiguration;
}
public static JMadModelDefinition findModelDefinitionFromUri(URI uri, Collection<JMadModelDefinition> candidates) {
String localPart = uri.getFragment();
checkArgument(!isNullOrEmpty(localPart), "No model information in URI");
String modelName = decodeUriComponent(localPart.split("&", 2)[0]);
return candidates.stream().filter(mDef -> mDef.getName().equalsIgnoreCase(modelName)).findFirst().orElseThrow(
() -> new NoSuchElementException(
"No model definition found for '" + modelName + "' in model pack identified by " + uri));
}
private static String encodeUriComponent(String string) {
try {
return URLEncoder.encode(string, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
private static String decodeUriComponent(String string) {
try {
return URLDecoder.decode(string, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException(e);
}
}
}