nl.mpi.tg.eg.experiment.client.service.ObfuscatedStorage.java Source code

Java tutorial

Introduction

Here is the source code for nl.mpi.tg.eg.experiment.client.service.ObfuscatedStorage.java

Source

/*
 * Copyright (C) 2019 Max Planck Institute for Psycholinguistics, Nijmegen
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package nl.mpi.tg.eg.experiment.client.service;

import com.google.gwt.http.client.URL;
import com.google.gwt.storage.client.Storage;
import nl.mpi.tg.eg.experiment.client.model.UserId;
import nl.mpi.tg.eg.frinex.common.model.Stimulus;

/**
 * @since Jan 16, 2019 3:26:06 PM (creation date)
 * @author Peter Withers <peter.withers@mpi.nl>
 */
public class ObfuscatedStorage {

    protected final String appNameInternal;
    protected final boolean enableObfuscation;
    private Storage dataStore = null;

    public ObfuscatedStorage(String appNameInternal, boolean enableObfuscation) {
        this.enableObfuscation = enableObfuscation;
        this.appNameInternal = obfuscateString(appNameInternal, appNameInternal);
    }

    public int getStorageLength() {
        // we could check the size of each item, but for now the length is enough
        return dataStore.getLength();
    }

    private String processString(String storageKey, String input) {
        if (enableObfuscation) {
            while (input.length() < 50) {
                input += " ";
            }
            byte[] outputBytes = input.getBytes();
            byte[] storageKeyBytes = storageKey.getBytes();
            for (int index = 0; index < input.length(); index++) {
                outputBytes[index] ^= storageKeyBytes[storageKeyBytes.length
                        - ((index * 3) % storageKeyBytes.length)];
            }
            return new String(outputBytes);
        } else {
            return input;
        }
    }

    private String obfuscateString(String storageKey, String input) {
        return processString(storageKey, URL.encode(input));
    }

    private String revealString(String storageKey, String input) {
        return URL.decode(processString(storageKey, input).trim());
    }

    public ObfuscatedStorage loadStorage() {
        if (dataStore == null) {
            dataStore = Storage.getLocalStorageIfSupported();
        }
        return (dataStore != null) ? this : null;
    }

    private String obfuscateStorageKey(UserId userId, String storageVariable) {
        return obfuscateString(userId.toString(), userId.toString() + storageVariable);
    }

    protected String getAPP_STATE(UserId userId) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".AppState");
    }

    protected String getCOMPLETION_CODE(UserId userId) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".completionCode");
    }

    protected String getUSER_RESULTS(UserId userId, String valueName) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".UserResults." + valueName);
    }

    protected String getUSER_METADATA(UserId userId, String valueName) {
        return appNameInternal + "." + userId.toString()
                + obfuscateString(appNameInternal, ".UserMetadata." + valueName);
    }

    protected boolean isUSER_METADATA(String keyName, String postName) {
        return keyName.startsWith(appNameInternal)
                && keyName.endsWith(obfuscateString(appNameInternal, ".UserMetadata." + postName));
    }

    protected String getUSER_METADATA_CONNECTION(UserId userId, String valueName) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".UserMetadataConnection." + valueName);
    }

    protected String getLAST_USER_ID() {
        return appNameInternal + obfuscateString(appNameInternal, ".LastUserId");
    }

    protected String getGAME_DATA(UserId userId) {
        // todo: perhaps merge game and screen data concepts
        return appNameInternal + "." + obfuscateStorageKey(userId, ".GameData");
    }

    protected String getGAME_DATA(String label, UserId userId) {
        // todo: perhaps merge game and screen data concepts
        return appNameInternal + "." + obfuscateStorageKey(userId, ".GameData." + label);
    }

    protected String getSTIMULI_DATA(UserId userId, Stimulus stimulus) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".StimuliData." + stimulus.getUniqueId());
    }

    protected String getSTIMULI_DATA(UserId userId, String stimulusId) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".StimuliData." + stimulusId);
    }

    protected String getSCREEN_DATA(String endPoint, UserId userId) {
        return appNameInternal + "." + obfuscateStorageKey(userId, ".ScreenData." + endPoint); // this is an exception in the order of the key parts, is this avoidable?
        //        STOWED_DATA = appNameInternal + ".SentData.";
        //        FAILED_DATA = appNameInternal + ".FailedData.";
    }

    public int getLength() {
        return dataStore.getLength();
    }

    public String key(int itemIndex) {
        return dataStore.key(itemIndex);
    }

    public String getItem(String key) {
        final String item = dataStore.getItem(key);
        return (item != null) ? revealString(key, item) : null;
    }

    public void setItem(String key, String data) {
        dataStore.setItem(key, obfuscateString(key, data));
    }

    public void removeItem(String key) {
        dataStore.removeItem(key);
    }

    public void clear() {
        dataStore.clear();
    }

    public void clearUserData(UserId userId) {
        for (int itemIndex = dataStore.getLength() - 1; itemIndex > -1; itemIndex--) {
            final String key = dataStore.key(itemIndex);
            if (key.startsWith(appNameInternal + "." + userId.toString())) {
                dataStore.removeItem(key);
            }
        }
    }
}