package org.eclipse.uml2.diagram.common.stereo; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.osgi.util.NLS; import org.eclipse.ui.IMemento; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; import org.eclipse.uml2.diagram.common.UMLCommonPlugin; import org.eclipse.uml2.diagram.common.preferences.UMLPreferencesConstants; import org.eclipse.uml2.uml.Profile; public class ProfileRegistry { private static ProfileRegistry myInstance; private final IPreferenceStore preferences; private static final String ELEMENT_PROFILE_REGISTRY = "profileRegistry"; //$NON-NLS-1$ private static final String ELEMENT_PROFILE = "profile"; //$NON-NLS-1$ private static final String ATTR_NAME = "name"; //$NON-NLS-1$ private static final String ATTR_URI = "uri"; //$NON-NLS-1$ private static final String ATTR_IS_BROKEN = "isBroken"; //$NON-NLS-1$ private ProfileRegistry() { preferences = UMLCommonPlugin.getInstance().getPreferenceStore(); } public static ProfileRegistry getInstance() { if (myInstance == null) { myInstance = new ProfileRegistry(); } return myInstance; } public List<ProfileInfo> getProfiles() { XMLMemento rootMemento = getRootMemento(); if (rootMemento == null) { return Collections.emptyList(); } List<ProfileInfo> result = new ArrayList<ProfileInfo>(); for (IMemento childMemento : rootMemento.getChildren(ELEMENT_PROFILE)) { ProfileInfo info = getProfileInfo(childMemento); if (info != null) { result.add(info); } } return result; } public void addProfile(Profile profile) { XMLMemento rootMemento = getOrCreateRootMemento(); IMemento memento = getMementoForProfile(rootMemento, getKey(profile)); if (memento != null) { storeProfileInMemento(profile, memento); } String str = getXMLString(rootMemento); saveInPreferences(str); } public String getPreferencesString(ProfileInfo... profiles) { XMLMemento root = createRootMenu(); if (profiles != null) { for (ProfileInfo profileInfo : profiles) { IMemento child = root.createChild(ELEMENT_PROFILE, profileInfo.uri); storeProfileInfoInMemento(profileInfo, child); } } return getXMLString(root); } private void markAsBroken(ProfileInfo info) { XMLMemento rootMemento = getOrCreateRootMemento(); markMementoAsBroken(getMementoForProfile(rootMemento, info.uri)); String str = getXMLString(rootMemento); saveInPreferences(str); } private String getXMLString(XMLMemento rootMemento) { StringWriter writer = new StringWriter(); try { rootMemento.save(writer); return writer.toString(); } catch (IOException e) { logError("Couldn't save Profile to Registry ", e); //$NON-NLS-1$ return null; } } private IMemento getMementoForProfile(IMemento containerMemento, String profileKey) { IMemento[] childMementos = containerMemento.getChildren(ELEMENT_PROFILE); for (IMemento child : childMementos) { if (profileKey.equals(child.getString(ATTR_URI))) { return child; } } IMemento child = containerMemento.createChild(ELEMENT_PROFILE, profileKey); child.putString(ATTR_URI, profileKey); return child; } private XMLMemento getRootMemento() { String str = getRegistryFromPreferences(); if (str == null || "".equals(str)) { //$NON-NLS-1$ return null; } try { XMLMemento rootMemento = XMLMemento.createReadRoot(new StringReader(str)); return rootMemento; } catch (WorkbenchException e) { logError("Couldn't get ProfileRegistry ", e); //$NON-NLS-1$ } return null; } private XMLMemento getOrCreateRootMemento() { XMLMemento rootMemento = getRootMemento(); if (rootMemento == null) { rootMemento = createRootMenu(); } return rootMemento; } private XMLMemento createRootMenu() { return XMLMemento.createWriteRoot(ELEMENT_PROFILE_REGISTRY); } private void storeProfileInMemento(Profile profile, IMemento memento) { memento.putString(ATTR_URI, EcoreUtil.getURI(profile).toString()); memento.putString(ATTR_NAME, profile.getName()); memento.putBoolean(ATTR_IS_BROKEN, false); } private void storeProfileInfoInMemento(ProfileInfo profile, IMemento memento) { memento.putString(ATTR_URI, profile.uri); memento.putString(ATTR_NAME, profile.name); memento.putBoolean(ATTR_IS_BROKEN, profile.isBroken); } private void markMementoAsBroken(IMemento memento) { memento.putBoolean(ATTR_IS_BROKEN, true); } private ProfileInfo getProfileInfo(IMemento memento) { return new ProfileInfo(memento.getString(ATTR_URI), memento.getString(ATTR_NAME), memento.getBoolean(ATTR_IS_BROKEN)); } private String getRegistryFromPreferences() { return preferences.getString(UMLPreferencesConstants.PREF_PROFILE_REGISTRY); } private void saveInPreferences(String str) { preferences.setValue(UMLPreferencesConstants.PREF_PROFILE_REGISTRY, str); } private String getKey(Profile profile) { return EcoreUtil.getURI(profile).toString(); } private static void logError(String message, Throwable e) { UMLCommonPlugin.getInstance().getLog().log(new Status(IStatus.ERROR, UMLCommonPlugin.getPluginId(), message, e)); } private static void logWarning(String message, Throwable e) { UMLCommonPlugin.getInstance().getLog().log(new Status(IStatus.WARNING, UMLCommonPlugin.getPluginId(), message, e)); } public static class ProfileInfo { public final String uri; public final String name; public final boolean isBroken; private ProfileInfo(String uri, String name, boolean isBroken) { this.uri = uri; this.name = name; this.isBroken = isBroken; } public ProfileInfo(String uri, String name) { this.uri = uri; this.name = name; this.isBroken = false; } public final Profile getProfile(Resource resource) { try { return (Profile) resource.getResourceSet().getEObject(URI.createURI(uri), true); } catch (Exception e) { ProfileRegistry.getInstance().markAsBroken(this); logWarning(NLS.bind("Couldn't load {1} for URI {0}", new Object[] { name, uri }), e); //$NON-NLS-1$ } return null; } } }