⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 propertymapimpl.java

📁 修正了jdk1.6中对托盘事件产生异常的bug.
💻 JAVA
字号:
/*
 * Copyright (C) 2004 NNL Technology AB
 * Visit www.infonode.net for information about InfoNode(R) 
 * products and how to contact NNL Technology AB.
 *
 * 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.
 */

// $Id: PropertyMapImpl.java,v 1.28 2005/12/04 13:46:06 jesper Exp $
package net.infonode.properties.propertymap;

import net.infonode.properties.base.Property;
import net.infonode.properties.base.exception.InvalidPropertyException;
import net.infonode.properties.propertymap.ref.*;
import net.infonode.properties.propertymap.value.PropertyRefValue;
import net.infonode.properties.propertymap.value.PropertyValue;
import net.infonode.properties.propertymap.value.ValueDecoder;
import net.infonode.properties.util.PropertyChangeListener;
import net.infonode.properties.util.PropertyPath;
import net.infonode.util.Printer;
import net.infonode.util.Utils;
import net.infonode.util.ValueChange;
import net.infonode.util.collection.map.ConstVectorMap;
import net.infonode.util.collection.map.MapAdapter;
import net.infonode.util.collection.map.SingleValueMap;
import net.infonode.util.collection.map.base.ConstMap;
import net.infonode.util.collection.map.base.ConstMapIterator;
import net.infonode.util.collection.map.base.MapIterator;
import net.infonode.util.collection.notifymap.AbstractConstChangeNotifyMap;
import net.infonode.util.collection.notifymap.ChangeNotifyMapWrapper;
import net.infonode.util.collection.notifymap.ConstChangeNotifyMap;
import net.infonode.util.collection.notifymap.ConstChangeNotifyVectorMap;
import net.infonode.util.signal.Signal;
import net.infonode.util.signal.SignalListener;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.*;

/**
 * @author $Author: jesper $
 * @version $Revision: 1.28 $
 */
public class PropertyMapImpl implements PropertyMap {
  private static final int SERIALIZE_VERSION = 1;

  private class PropertyObjectMap extends AbstractConstChangeNotifyMap implements SignalListener {
    private boolean listenerActive;

    PropertyObjectMap() {
    }

    protected void listenerAdded() {
      if (!listenerActive) {
        listenerActive = true;
        addInheritedReferences();
        superMap.getChangeSignal().add(this);
      }
    }

    public void signalEmitted(Signal signal, Object object) {
      ConstMap changes = (ConstMap) object;
      MapAdapter m = new MapAdapter();

      for (ConstMapIterator iterator = changes.constIterator(); iterator.atEntry(); iterator.next()) {
        Property property = (Property) iterator.getKey();

        if (propertyGroup.hasProperty(property)) {
          PropertyValue currentValue = (PropertyValue) values.get(property);

          if (currentValue == null || currentValue.getParent() != null) {
            ValueChange vc = (ValueChange) iterator.getValue();
            PropertyValue superValue = (PropertyValue) vc.getNewValue();
            PropertyValue newValue = superValue == null ? null : superValue.getSubValue(PropertyMapImpl.this);
            internalSetValue(property, newValue);
            m.put(property, new ValueChange(currentValue != null ? currentValue : vc.getOldValue(),
                                            newValue != null ? newValue : vc.getNewValue()));
          }
        }
      }

      if (!m.isEmpty())
        fireEntriesChanged(m);
    }

    protected void lastListenerRemoved() {
      if (listenerActive) {
        listenerActive = false;
        superMap.getChangeSignal().remove(this);
        removeInheritedReferences();
      }
    }

    public boolean checkListeners(Set visited) {
      for (Iterator it = getChangeSignalInternal().iterator(); it.hasNext();) {
        Object l = it.next();

        if (l instanceof PropertyRefValue) {
          PropertyRefValue v = (PropertyRefValue) l;

          if (v.getMap().checkListeners(visited))
            return true;
        }
      }

      return false;
    }

    public void updateListeners() {
      for (Iterator it = getChangeSignalInternal().iterator(); it.hasNext();) {
        if (!(it.next() instanceof PropertyRefValue)) {
          return;
        }
      }

      for (Iterator it = getChangeSignalInternal().iterator(); it.hasNext();) {
        Object l = it.next();

        if (l instanceof PropertyRefValue) {
          PropertyRefValue v = (PropertyRefValue) l;

          if (v.getMap().checkListeners(new HashSet())) {
            return;
          }
        }
      }

      lastListenerRemoved();
    }

    private void addInheritedReferences() {
      for (ConstMapIterator iterator = values.constIterator(); iterator.atEntry(); iterator.next()) {
        Property property = (Property) iterator.getKey();
        PropertyValue currentValue = (PropertyValue) values.get(property);
        currentValue.updateListener(true);
      }

      for (ConstMapIterator iterator = superMap.constIterator(); iterator.atEntry(); iterator.next()) {
        Property property = (Property) iterator.getKey();

        if (propertyGroup.hasProperty(property)) {
          PropertyValue currentValue = (PropertyValue) values.get(property);

          if (currentValue == null || currentValue.getParent() != null) {
            PropertyValue superValue = (PropertyValue) iterator.getValue();
            PropertyValue newValue = superValue == null ? null : superValue.getSubValue(PropertyMapImpl.this);
            internalSetValue(property, newValue);
          }
        }
      }
    }

    private void removeInheritedReferences() {
      ArrayList toBeRemoved = new ArrayList();

      for (ConstMapIterator iterator = values.constIterator(); iterator.atEntry(); iterator.next()) {
        Property property = (Property) iterator.getKey();
        PropertyValue currentValue = (PropertyValue) values.get(property);

        if (currentValue.getParent() != null) {
          currentValue.unset();
          toBeRemoved.add(property);
        }
        else {
          currentValue.updateListener(false);
        }
      }

      for (int i = 0; i < toBeRemoved.size(); i++) {
        values.remove(toBeRemoved.get(i));
      }
    }

    public Object get(Object key) {
      return vectorMap.get(key);
    }

    public boolean containsKey(Object key) {
      return vectorMap.containsKey(key);
    }

    public boolean containsValue(Object value) {
      return vectorMap.containsValue(value);
    }

    public boolean isEmpty() {
      return vectorMap.isEmpty();
    }

    public ConstMapIterator constIterator() {
      return vectorMap.constIterator();
    }

    protected void fireEntriesChanged(ConstMap changes) {
      super.fireEntriesChanged(changes);
    }
  }

  private PropertyMapGroup propertyGroup;
  private PropertyMapImpl parent;
  private PropertyMapProperty property;

  private ChangeNotifyMapWrapper values = new ChangeNotifyMapWrapper(new MapAdapter());
  private ConstChangeNotifyVectorMap superMap = new ConstChangeNotifyVectorMap();
  private ConstVectorMap vectorMap = new ConstVectorMap();
  private PropertyObjectMap map = new PropertyObjectMap();

  private ArrayList superMaps = new ArrayList(1);
  private MapAdapter childMaps = new MapAdapter();

  private HashMap propertyChangeListeners;
  private ArrayList listeners;
  private ArrayList treeListeners;

  private SignalListener mapListener;

  public PropertyMapImpl(PropertyMapGroup propertyGroup) {
    this(propertyGroup, null);
  }

  public PropertyMapImpl(PropertyMapImpl inheritFrom) {
    this(inheritFrom.getPropertyGroup(), inheritFrom);
  }

  public PropertyMapImpl(PropertyMapGroup propertyGroup, PropertyMapImpl superObject) {
    this(propertyGroup, null, null);

    if (superObject != null)
      addSuperMap(superObject);
  }

  public PropertyMapImpl(PropertyMapImpl parent, PropertyMapProperty property) {
    this(property.getPropertyMapGroup(), parent, property);
  }

  public PropertyMapImpl(PropertyMapGroup propertyGroup, PropertyMapImpl parent, PropertyMapProperty property) {
    this.parent = parent;
    this.property = property;
    this.propertyGroup = propertyGroup;

    Property[] properties = this.propertyGroup.getProperties();

    for (int i = 0; i < properties.length; i++) {
      if (properties[i] instanceof PropertyMapProperty) {
        PropertyMapProperty p = (PropertyMapProperty) properties[i];
        PropertyMapImpl propertyObject = new PropertyMapImpl(this, p);
        childMaps.put(p, propertyObject);
      }
    }

    vectorMap.addMap(values);
    vectorMap.addMap(superMap);
  }

  private boolean hasTreeListener() {
    return (treeListeners != null && treeListeners.size() > 0) || (parent != null && parent.hasTreeListener());
  }

  private boolean hasListener() {
    return hasTreeListener() ||
           (listeners != null && listeners.size() > 0) ||
           (propertyChangeListeners != null && propertyChangeListeners.size() > 0);
  }

  private void updateListenerRecursive() {
    updateListener();

    for (ConstMapIterator iterator = childMaps.constIterator(); iterator.atEntry(); iterator.next())
      ((PropertyMapImpl) iterator.getValue()).updateListenerRecursive();
  }

  private void updateListener() {
    if (hasListener()) {
      if (mapListener == null) {
        mapListener = new SignalListener() {
          public void signalEmitted(Signal signal, Object object) {
            PropertyMapManager.getInstance().addMapChanges(PropertyMapImpl.this, (ConstMap) object);
          }
        };

        map.getChangeSignal().add(mapListener);
      }
    }
    else {
      if (mapListener != null) {
        map.getChangeSignal().remove(mapListener);
        mapListener = null;
        map.updateListeners();
      }
    }
  }

  private boolean checkListeners(Set visited) {
    if (visited.contains(this))
      return false;

    visited.add(this);
    return hasListener() || map.checkListeners(visited);
  }

  public ConstChangeNotifyMap getMap() {
    return map;
  }

  public PropertyMap getSuperMap() {
    return superMaps.size() == 0 ? null : (PropertyMap) superMaps.get(0);
  }

  public Object removeValue(Property property) throws InvalidPropertyException {
    checkProperty(property);
    PropertyValue value = (PropertyValue) values.get(property);

    // Can't removeValue not set values or inherited reference values
    if (value == null || value.getParent() != null)
      return null;

    values.remove(property);

    PropertyMapManager.getInstance().beginBatch();

    try {
      firePropertyValueChanged(property, new ValueChange(value, getValue(property)));
    }
    finally {
      PropertyMapManager.getInstance().endBatch();
    }

    return value.get(this);
  }

  private PropertyMapRef getPathFrom(PropertyMapImpl parentObject) {
    if (parent == null)
      return null;

    if (parent == parentObject)
      return new PropertyMapPropertyRef(property);

    PropertyMapRef parentRef = parent.getPathFrom(parentObject);
    return parentRef == null ? null : new CompositeMapRef(parentRef, new PropertyMapPropertyRef(property));
  }

  private PropertyMapRef getRelativePathTo(PropertyMapImpl propertyObject) {
    PropertyMapRef ref = propertyObject == this ? ThisPropertyMapRef.INSTANCE : propertyObject.getPathFrom(this);
    return ref == null ?
           parent == null ?
           null : new CompositeMapRef(ParentMapRef.INSTANCE, parent.getRelativePathTo(propertyObject)) :
           ref;
  }

  public Object createRelativeRef(Property fromProperty, PropertyMap toObject, Property toProperty) {
    PropertyValue value = setValue(fromProperty,
                                   new PropertyRefValue(this,
                                                        fromProperty,
                                                        getRelativePathTo((PropertyMapImpl) toObject),
                                                        toProperty,
                                                        null));
    return value == null ? null : value.getWithDefault(this);
  }

  public int getSuperMapCount() {
    return superMaps.size();
  }

  public void addSuperMap(PropertyMap superMap) {
    PropertyMapImpl superMapImpl = (PropertyMapImpl) superMap;

/*    if (!propertyObjectImpl.propertyGroup.isA(propertyGroup))
      throw new RuntimeException("Property group '" + propertyObjectImpl.propertyGroup + "

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -