/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.core.internal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.xmind.core.ICloneData; public class CloneData implements ICloneData { private static class CategorizedString { private String category; private String source; public CategorizedString(String category, String source) { this.category = category; this.source = source; } /* * (non-Javadoc) * * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (obj == null || !(obj instanceof CategorizedString)) return false; CategorizedString that = (CategorizedString) obj; return this.category.equals(that.category) && this.source.equals(that.source); } /* * (non-Javadoc) * * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return this.category.hashCode() ^ this.source.hashCode(); } } private Collection<Object> sources; private ICloneData parent; private Map<Object, Object> clonedElements = new HashMap<Object, Object>(); private Map<Object, List<ICloneDataListener>> listeners = new HashMap<Object, List<ICloneDataListener>>(); private Map<Object, Object> caches = new HashMap<Object, Object>(); public CloneData(Collection<? extends Object> sources, ICloneData parent) { this.sources = new ArrayList<Object>(sources); this.parent = parent; } public String getString(String category, String source) { return (String) get(new CategorizedString(category, source)); } public void putString(String category, String source, String cloned) { CategorizedString sourceObj = new CategorizedString(category, source); doPut(sourceObj, cloned); fireStringCloned(sourceObj, category, source, cloned); } public Object get(Object source) { Object cloned = clonedElements.isEmpty() ? null : clonedElements .get(source); if (cloned == null && parent != null) cloned = parent.get(source); return cloned; } public boolean hasCloned() { if (!clonedElements.isEmpty()) { for (Object cloned : clonedElements.values()) if (cloned != null) return true; } if (parent != null) return parent.hasCloned(); return false; } public Collection<Object> getCloneds() { ArrayList<Object> list = new ArrayList<Object>(sources.size()); for (Object source : sources) { Object cloned = get(source); if (cloned != null) list.add(cloned); } return list; } public Collection<Object> getSources() { return sources; } public ICloneData getParent() { return parent; } public void put(Object source, Object cloned) { doPut(source, cloned); fireObjectCloned(source, cloned); } protected void doPut(Object source, Object cloned) { clonedElements.put(source, cloned); if (parent != null) { parent.put(source, cloned); } } public void cache(Object key, Object value) { caches.put(key, value); } public Object getCache(Object key) { return caches.isEmpty() ? null : caches.get(key); } private void fireObjectCloned(Object source, Object cloned) { if (listeners.isEmpty()) return; List<ICloneDataListener> list = listeners.get(source); if (list == null || list.isEmpty()) { listeners.remove(source); return; } for (Object o : list.toArray()) { ((ICloneDataListener) o).objectCloned(source, cloned); } } private void fireStringCloned(Object sourceObj, String category, String source, String cloned) { if (listeners.isEmpty()) return; List<ICloneDataListener> list = listeners.get(sourceObj); if (list == null || list.isEmpty()) { listeners.remove(sourceObj); return; } for (Object o : list.toArray()) { ((ICloneDataListener) o).stringCloned(category, source, cloned); } } public void addCloneDataListener(Object source, ICloneDataListener listener) { List<ICloneDataListener> list = listeners.get(source); if (list == null) { list = new ArrayList<ICloneDataListener>(); listeners.put(source, list); } list.add(listener); } public void removeCloneDataListener(Object source, ICloneDataListener listener) { if (listeners.isEmpty()) return; List<ICloneDataListener> list = listeners.get(source); if (list == null) return; list.remove(listener); if (list.isEmpty()) listeners.remove(source); } public void addCloneDataListener(String category, String source, ICloneDataListener listener) { addCloneDataListener(new CategorizedString(category, source), listener); } public void removeCloneDataListener(String category, String source, ICloneDataListener listener) { removeCloneDataListener(new CategorizedString(category, source), listener); } public boolean isCloned(Object source) { if (clonedElements != null && clonedElements.containsKey(source)) return true; return parent != null && parent.isCloned(source); } /* * (non-Javadoc) * * @see org.xmind.core.ICloneData#isCloned(java.lang.String, * java.lang.String) */ public boolean isCloned(String category, String source) { return isCloned(new CategorizedString(category, source)); } // public String getString(String sourceString) { // Object cloned = clonedElements == null ? null : clonedElements // .get(sourceString); // if ((cloned == null || !(cloned instanceof String)) && parent != null) { // cloned = parent.get(sourceString); // } // return cloned instanceof String ? (String) cloned : null; // } }