// Copyright 2012 Google Inc. All Rights Reserved. // // 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 org.eclipse.che.ide.collections.js; import org.eclipse.che.ide.collections.Jso; import org.eclipse.che.ide.collections.StringMap; import com.google.gwt.core.client.JavaScriptObject; /** * This is used to satisfy DTO casting requirements. * <p/> * On the client, if you have a reference to StringMap, or JsoStringMap * (the JavaScriptObject backed impl), feel free to cross cast this to the more * robust {@link com.codenvy.ide.collections.Jso}. */ public final class JsoStringMap<T> extends JavaScriptObject implements StringMap<T> { /* * GWT dev mode adds a __gwt_ObjectId property to all objects. We have to call * hasOwnProperty (which is overridden by GWT) when using for(in) loops to verify * that the key is actually a property of the object, and not the __gwt_ObjectId * set by Chrome dev mode. */ /** Convenience factory method. */ public static <T> JsoStringMap<T> create() { return Jso.create().cast(); } protected JsoStringMap() { } @Override public native T get(String key) /*-{ return Object.prototype.hasOwnProperty.call(this, key) ? this[key] : undefined; }-*/; @Override public native final JsoArray<String> getKeys() /*-{ keys = []; for (key in this) { if (Object.prototype.hasOwnProperty.call(this, key)) { keys.push(key); } } return keys; }-*/; @Override public final native boolean isEmpty()/*-{ for (key in this) { if (Object.prototype.hasOwnProperty.call(this, key)) { return false; } } return true; }-*/; /** * Method for iterating through the contents of a Map. * <p/> * <p>{@code T} is the expected type of the values returned from the map. * <b>Caveat:</b> if you have a map of heterogeneous types, you need to think * what value of T you specify here. * * @param callback * The callback object that gets called on each iteration. */ @Override public native void iterate(IterationCallback<T> callback) /*-{ for (key in this) { if (Object.prototype.hasOwnProperty.call(this, key)) { callback. @org.eclipse.che.ide.collections.StringMap.IterationCallback::onIteration(Ljava/lang/String;Ljava/lang/Object;) (key, this[key]); } } }-*/; // TODO: We still have problem with "__proto__" @Override public native void put(String key, T value) /*-{ this[key] = value; }-*/; @Override public void putAll(StringMap<T> map) { map.iterate(new IterationCallback<T>() { @Override public void onIteration(String key, T value) { put(key, value); } }); } @Override public native T remove(String key) /*-{ if (!Object.prototype.hasOwnProperty.call(this, key)) { return undefined; } var retVal = this[key]; delete this[key]; return retVal; }-*/; @Override public native boolean containsKey(String key) /*-{ return Object.prototype.hasOwnProperty.call(this, key); }-*/; /** * Returns the size of the map (the number of keys). * <p/> * <p>NB: This method is currently O(N) because it iterates over all keys. * * @return the size of the map. */ @Override public final native int size() /*-{ size = 0; for (key in this) { if (Object.prototype.hasOwnProperty.call(this, key)) { size++; } } return size; }-*/; /** {@inheritDoc} */ public final native JsoArray<T> getValues() /*-{ var data = []; for (var i in this) { if (Object.prototype.hasOwnProperty.call(this, key)) { data.push(this[i]); } } return data; }-*/; }