如何使用EMF保存视图部分

3
我正在开发一个Eclipse RPC项目,需要保存并恢复所有视图的内容。由于我的项目中没有使用EMF,所以无法使用EMF API。
现在我可以使用的是IMemento。IViewPart有一个saveState方法,其中参数是IMemento。
我正在调用saveState()并尝试将其放入视图中。
示例代码:
@Override
public void saveState(IMemento memento) {
   ColorBarModel model =  _multiColorBarContainer.getColorBar().getColorBarUIModel().getModel();
   boolean isCutOff = _multiColorBarContainer.getColorBar().getColorBarUIModel().isCutOffEnabled();
   String colorMapName = model.getColorMap().getColorMapName();
   memento.putString("colorMapName", model.toString());
   memento.createChild("colorMapName1", model.toString());
   String selectionsMomento = memento.getString("colorMapName");
   IStructuredSelection ss = new StructuredSelection(memento.getChild("colorMapName1"));
 }

我需要保存一个类的引用,该类是视图的模型(ColorBarModel.java是我的视图模型),以便保存模型状态,并在调用时恢复它。

但是IMemento只提供了putString()createChild()方法。

有人能指导我如何通过IMemento保存类对象并在需要时恢复吗?

我能够保存该类的引用ID,但我不确定如何通过字符串形式的referenceId获取该类的属性和行为。

是否可以通过某种方式进行提取?


1
你需要存储什么样的信息?IMemento仅适用于相对较小量的字符串。 - greg-449
我想存储整个模型的信息,有任何建议吗? - Arun
4个回答

0
如果你比较懒,可以使用Google的GSON将模型转换为JSON并将其存储为字符串。 然后,您可以再次使用GSON从JSON字符串中加载定义的类。

0

IMemento 提供了一个使用层次结构将视图状态存储为 XML 的接口。您可以:

  • 调用模型的方法并尝试在 XML 结构中表示它,以便在视图的 init 方法中重新创建
  • 将模型存储在磁盘上,并在 memento 中引用它(例如路径)
  • 将复杂对象序列化为字节,将其转换为 Base64 String 并将其放入 memento 中

0

我创建了一个名为SimpleModelSerializer的类,以便能够轻松地将EMF模型写入和读取到不同的格式中。使用readMementowriteMemento方法处理IMemento。该类可以轻松扩展以适用于其他格式。

它非常简洁,只能处理简单的模型。以下是一些限制:

  • 不处理非包含引用
  • 不处理特征值的子类型化
  • EPackages必须在全局包注册表中。
  • 它可能会在许多有效模型上崩溃。
  • 不执行验证。
  • 对扩展元数据的支持非常有限。
  • 还有很多其他事情...

尽管如此,它对于保存小而简单的东西(如视图配置)非常有用。

这是代码:

/**
 * Contains code for reading and writing EMF models to and from other formats.
 */
public class SimpleModelSerializer {
    public interface ModelReader {
        List<String> getMultiAttribute(String name);
        String getAttribute(String name);
        String getDefaultAttribute(String name);
        List<ModelReader> getChildren(String name);
    }

    public interface ModelWriter {
        void setAttribute(String name, String value);
        void setDefaultAttribute(String name, String value);
        void setMultiAttribute(String name, List<String> values);
        ModelWriter createChild(String name);
    }

    @SuppressWarnings("unchecked")
    private static void setFeature(EObject o, EStructuralFeature feature, Object value) {
        if (feature.isMany()) {
            ((List<Object>) o.eGet(feature)).add(value);
        } else {
            o.eSet(feature, value);
        }
    }

    @SuppressWarnings("unchecked")
    private static List<?> getFeature(EObject o, EStructuralFeature feature) {
        if (feature.isMany()) {
            return (List<Object>) o.eGet(feature);
        } else {
            return Collections.singletonList(o.eGet(feature));
        }
    }

    public static <T extends EObject> T readMemento(IMemento mem, EClass cls, Class<T> instCls, ExtendedMetaData meta) {
        return readCastedObject(cls, instCls, new MementoReader(mem), meta);
    }

    public static <T extends EObject> List<T> readMementos(IMemento mem, String name, EClass cls, Class<T> instCls, ExtendedMetaData meta) {
        return readObjects(cls, instCls,  new MementoReader(mem), name, meta);
    }


    public static <T extends EObject> List<T> readObjects(EClass cls, Class<T> instCls, ModelReader reader, String name, ExtendedMetaData meta) {
        List<T> result = new ArrayList<>();
        for (ModelReader childReader : reader.getChildren(name)) {
            result.add(instCls.cast(readObject(cls, childReader, meta)));
        }
        return result;
    }

    public static <T extends EObject> T readCastedObject(EClass cls, Class<T> instCls, ModelReader reader, ExtendedMetaData meta) {
        return instCls.cast(readObject(cls, reader, meta));
    }


    public static EObject readObject(EClass cls, ModelReader reader, ExtendedMetaData meta) {
        if (meta == null) meta = ExtendedMetaData.INSTANCE;

        EObject obj = EcoreUtil.create(cls);

        for (EStructuralFeature feature : cls.getEAllStructuralFeatures()) {
            if (feature.isTransient()) continue;

            String name = meta.getName(feature);

            List<Object> values = new ArrayList<>();

            if (feature instanceof EAttribute) {
                EAttribute attr = (EAttribute) feature;

                List<String> attrs;
                if (attr.isMany()) attrs = reader.getMultiAttribute(name);
                else if (name.equals(":0")) attrs = singletonList(reader.getDefaultAttribute(name));
                else attrs = singletonList(reader.getAttribute(name));

                for (String attrText : attrs) {
                    if (attrText != null) {
                        values.add(EcoreUtil.createFromString(attr.getEAttributeType(), attrText));
                    }
                }
            } else if (feature instanceof EReference) {
                EReference ref = (EReference) feature;

                for (ModelReader childReader : reader.getChildren(name)) {
                    values.add(readObject(ref.getEReferenceType(), childReader, meta));
                }
            }

            for (Object value : values) {
                setFeature(obj, feature, value);
            }
        }

        return obj;
    }

    public static void writeMemento(IMemento mem, EObject o, ExtendedMetaData meta) {
        writeObject(new MementoWriter(mem), o, meta);
    }

    public static void writeMementos(IMemento mem, String childName,  Collection<? extends EObject> os, ExtendedMetaData meta) {
        MementoWriter writer = new MementoWriter(mem);
        for (EObject o : os) {
            writeObject(writer.createChild(childName), o, meta);
        }
    }


    public static void writeObject(ModelWriter writer, EObject obj, ExtendedMetaData meta) {
        if (meta == null) meta = ExtendedMetaData.INSTANCE;

        EClass cls = obj.eClass();

        for (EStructuralFeature feature : cls.getEAllStructuralFeatures()) {
            if (feature.isTransient()) continue;

            String name = meta.getName(feature);

            if (feature instanceof EAttribute) {
                List<String> outputValues = new ArrayList<>();
                for (Object e : getFeature(obj, feature)) {
                    if (!Objects.equals(e, feature.getDefaultValue())) {
                        String textValue = EcoreUtil.convertToString((EDataType) feature.getEType(), e);
                        outputValues.add(textValue);
                    }
                }

                if (feature.isMany()) {
                    writer.setMultiAttribute(name, outputValues);
                } else if (!outputValues.isEmpty()) {
                    if (name.equals(":0")) {
                        writer.setDefaultAttribute(name, outputValues.get(0));
                    } else {
                        writer.setAttribute(name, outputValues.get(0));
                    }
                }
            } else if (feature instanceof EReference) {
                for (Object value : getFeature(obj, feature)) {
                    if (value != null) {
                        writeObject(writer.createChild(name), (EObject) value, meta);
                    }
                }
            }
        }
    }

    private static class MementoReader implements ModelReader {
        private final IMemento memento;

        public MementoReader(IMemento memento) {
            this.memento = memento;
        }

        @Override
        public String getDefaultAttribute(String name) {
            return memento.getTextData();
        }

        @Override
        public String getAttribute(String name) {
            return memento.getString(name);
        }

        @Override
        public List<String> getMultiAttribute(String name) {
            IMemento[] childMems = memento.getChildren(name);
            List<String> attrs = new ArrayList<>(childMems.length);
            for (IMemento mem : childMems) {
                attrs.add(mem.getTextData());
            }
            return attrs;
        }

        @Override
        public List<ModelReader> getChildren(String name) {
            return Arrays.stream(memento.getChildren(name)).map(MementoReader::new).collect(toList());
        }
    }

    private static class MementoWriter implements ModelWriter {
        private final IMemento memento;

        public MementoWriter(IMemento memento) {
            this.memento = memento;
        }

        @Override
        public void setAttribute(String name, String value) {
            memento.putString(name, value);
        }

        @Override
        public void setMultiAttribute(String name, List<String> values) {
            for (String value : values) {
                memento.createChild(name).putTextData(value);
            }
        }

        @Override
        public ModelWriter createChild(String name) {
            return new MementoWriter(memento.createChild(name));
        }

        @Override
        public void setDefaultAttribute(String name, String value) {
            memento.putTextData(value);
        }
    }
}

0
如果您想保存大量数据,应将其放置在插件状态位置。您可以通过以下方式获得此位置:
IPath path = Platform.getStateLocation(bundle);

bundle 是你的插件的 Bundle 类。你可以从传递给插件激活器的 BundleContext 中获取它,或者使用其他方法。

Bundle bundle = Platform.getBundle("plugin id");

状态位置在工作区 .metadata/.plugins 目录中。只需使用普通的 Java 文件 I/O 操作来读写此位置中的数据。

谢谢您的建议,但您能否详细说明如何将整个模型信息保存到Ipath中,我能找到捆绑包,但不确定如何存储。这将是非常有帮助的。 - Arun
我的模型包含大约10到20个变量,我需要存储并希望在其他启动中恢复。所以这对我来说很繁琐。不幸的是,我的项目不是EMF模型,因此我无法使用EMF API :( - Arun
我不了解你的代码,所以我不知道如何进一步提供建议。 - greg-449
对不起,格雷格,我道歉。你能给出一个普通的Java模型的例子吗?就像任何视图都有一些数据,这些数据由某个ModelImpl提供。所以我需要存储那个模型并恢复它...请提供一些通过Ipath存储Java对象状态的伪代码。那将是非常有帮助的。 - Arun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接