/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.ide.statepersistance; import elemental.json.Json; import elemental.json.JsonException; import elemental.json.JsonFactory; import elemental.json.JsonObject; import com.google.inject.Inject; import com.google.inject.Singleton; import org.eclipse.che.api.promises.client.Operation; import org.eclipse.che.api.promises.client.OperationException; import org.eclipse.che.api.promises.client.Promise; import org.eclipse.che.api.promises.client.PromiseError; import org.eclipse.che.ide.api.component.StateComponent; import org.eclipse.che.ide.api.preferences.PreferencesManager; import org.eclipse.che.ide.util.loging.Log; import java.util.Map; /** * Responsible for persisting and restoring IDE state across sessions. * Uses user preferences as storage for serialized state. * * @author Artem Zatsarynnyi * @author Yevhen Vydolob */ @Singleton public class AppStateManager { /** The name of the property for the mappings in user preferences. */ public static final String PREFERENCE_PROPERTY_NAME = "IdeAppStates"; private static final String WORKSPACE = "workspace"; private final Map<String, StateComponent> persistenceComponents; private final PreferencesManager preferencesManager; private final JsonFactory jsonFactory; private JsonObject allWsState; @Inject public AppStateManager(Map<String, StateComponent> persistenceComponents, PreferencesManager preferencesManager, JsonFactory jsonFactory) { this.persistenceComponents = persistenceComponents; this.preferencesManager = preferencesManager; this.jsonFactory = jsonFactory; readStateFromPreferences(); } private void readStateFromPreferences() { final String json = preferencesManager.getValue(PREFERENCE_PROPERTY_NAME); if (json == null) { allWsState = jsonFactory.createObject(); } else { try { allWsState = jsonFactory.parse(json); } catch (Exception e) { // create 'clear' state if any deserializing error occurred allWsState = jsonFactory.createObject(); } } } public void restoreWorkspaceState(String wsId) { if (allWsState.hasKey(wsId)) { restoreState(allWsState.getObject(wsId)); } } private void restoreState(JsonObject settings) { try { if (settings.hasKey(WORKSPACE)) { JsonObject workspace = settings.getObject(WORKSPACE); for (String key : workspace.keys()) { if (persistenceComponents.containsKey(key)) { StateComponent component = persistenceComponents.get(key); component.loadState(workspace.getObject(key)); } } } } catch (JsonException e) { Log.error(getClass(), e); } } public Promise<Void> persistWorkspaceState(String wsId) { final JsonObject settings = Json.createObject(); JsonObject workspace = Json.createObject(); settings.put(WORKSPACE, workspace); for (Map.Entry<String, StateComponent> entry : persistenceComponents.entrySet()) { try { String key = entry.getKey(); workspace.put(key, entry.getValue().getState()); } catch (Exception e) { Log.error(getClass(), e); } } allWsState.put(wsId, settings); return writeStateToPreferences(allWsState); } private Promise<Void> writeStateToPreferences(JsonObject state) { final String json = state.toJson(); preferencesManager.setValue(PREFERENCE_PROPERTY_NAME, json); return preferencesManager.flushPreferences().catchError(new Operation<PromiseError>() { @Override public void apply(PromiseError arg) throws OperationException { Log.error(AppStateManager.class, "Failed to store app's state to user's preferences"); } }); } public boolean hasStateForWorkspace(String wsId) { return allWsState.hasKey(wsId); } }