/*
* Copyright 2003-2015 JetBrains s.r.o.
*
* Licensed 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 jetbrains.mps.nodefs;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.module.SModule;
import org.jetbrains.mps.openapi.module.SRepository;
/**
* Provide nice reference presentation for nodes/models/modules using names, be careful - can be not persistent in case of node/model/module changes.
* Format: {module_name}/{model_name}/{node_presentation}. In case of names ambiguity format becomes name~{id} like DOS fs.
*
* FIXME works with root nodes only, references to children nodes would never get de-serialized.
*/
/*package*/ class NiceReferenceSerializer {
private static final String SEP = "/";
private final SRepository myRepository;
public NiceReferenceSerializer(SRepository repository) {
myRepository = repository;
}
// module
public String serializeModule(SModule module) {
return serialize(module, myRepository.getModules(), MODULE_TARGET);
}
@Nullable
public SModule deserializeModule(String s) {
return deserialize(s, myRepository.getModules(), MODULE_TARGET);
}
// model
public String serializeModel(SModel model) {
return serializeModule(model.getModule()) + SEP + serialize(model, model.getModule().getModels(), MODEL_TARGET);
}
@Nullable
public SModel deserializeModel(String s) {
if (!s.contains("/")) {
return null;
}
SModule module = deserializeModule(s.substring(0, s.lastIndexOf(SEP)));
if (module == null) {
return null;
}
return deserialize(s.substring(s.lastIndexOf(SEP) + 1), module.getModels(), MODEL_TARGET);
}
// node
public String serializeNode(SNode node) {
return serializeModel(node.getModel()) + SEP + serialize(node, node.getModel().getRootNodes(), NODE_TARGET);
}
@Nullable
public SNode deserializeNode(String s) {
if (!s.contains(SEP)) {
return null;
}
SModel model = deserializeModel(s.substring(0, s.lastIndexOf(SEP)));
if (model == null) {
return null;
}
return deserialize(s.substring(s.lastIndexOf(SEP) + 1), model.getRootNodes(), NODE_TARGET);
}
// common
/**
* @return serialization without SEP character
*/
@NotNull
private static <T> String serialize(T e, Iterable<T> contextElements, SerializerTarget<T> target) {
// todo: implement name~2 format
return target.getName(e);
}
@Nullable
private static <T> T deserialize(@NotNull String s, Iterable<T> contextElements, SerializerTarget<T> target) {
// todo: implement name~2 format
for (T e : contextElements) {
if (s.equals(target.getName(e))) {
return e;
}
}
return null;
}
// serialization targets
private static final SerializerTarget<SNode> NODE_TARGET = new SerializerTarget<SNode>() {
@Override
public String getName(SNode e) {
return String.valueOf(e.getPresentation());
}
};
private static final SerializerTarget<SModel> MODEL_TARGET = new SerializerTarget<SModel>() {
@Override
public String getName(SModel e) {
return String.valueOf(e.getModelName());
}
};
private static final SerializerTarget<SModule> MODULE_TARGET = new SerializerTarget<SModule>() {
@Override
public String getName(SModule e) {
return String.valueOf(e.getModuleName());
}
};
private interface SerializerTarget<T> {
@NotNull
String getName(T e);
}
}