Home | History | Annotate | Download | only in property
      1 /*******************************************************************************
      2  * Copyright (c) 2011 Google, Inc.
      3  * All rights reserved. This program and the accompanying materials
      4  * are made available under the terms of the Eclipse Public License v1.0
      5  * which accompanies this distribution, and is available at
      6  * http://www.eclipse.org/legal/epl-v10.html
      7  *
      8  * Contributors:
      9  *    Google, Inc. - initial API and implementation
     10  *******************************************************************************/
     11 package org.eclipse.wb.internal.core.editor.structure.property;
     12 
     13 import com.google.common.collect.Lists;
     14 
     15 import org.eclipse.wb.internal.core.model.property.Property;
     16 import org.eclipse.wb.internal.core.model.property.PropertyManager;
     17 
     18 import java.util.Iterator;
     19 import java.util.List;
     20 
     21 /**
     22  * Helper for computing intersection of {@link Property} arrays.
     23  *
     24  * @author scheglov_ke
     25  * @coverage core.editor.structure
     26  */
     27 public final class PropertyListIntersector {
     28   private List<PropertyGroup> m_intersection;
     29 
     30   ////////////////////////////////////////////////////////////////////////////
     31   //
     32   // Access
     33   //
     34   ////////////////////////////////////////////////////////////////////////////
     35   /**
     36    * Updates intersection by intersecting with new given array.
     37    */
     38   public void intersect(Property[] properties) {
     39     if (m_intersection == null) {
     40       m_intersection = Lists.newArrayList();
     41       for (int i = 0; i < properties.length; i++) {
     42         Property property = properties[i];
     43         m_intersection.add(new PropertyGroup(property));
     44       }
     45     } else {
     46       for (Iterator<PropertyGroup> I = m_intersection.iterator(); I.hasNext();) {
     47         PropertyGroup propertyGroup = I.next();
     48         if (!propertyGroup.add(properties)) {
     49           I.remove();
     50         }
     51       }
     52     }
     53   }
     54 
     55   /**
     56    * @return the array of matched composite {@link Property}'s.
     57    */
     58   public Property[] getProperties() {
     59     List<Property> properties = Lists.newArrayList();
     60     for (PropertyGroup propertyGroup : m_intersection) {
     61       Property compositeProperty = propertyGroup.getCompositeProperty();
     62       if (compositeProperty != null) {
     63         properties.add(compositeProperty);
     64       }
     65     }
     66     //
     67     return properties.toArray(new Property[properties.size()]);
     68   }
     69 
     70   ////////////////////////////////////////////////////////////////////////////
     71   //
     72   // PropertyGroup
     73   //
     74   ////////////////////////////////////////////////////////////////////////////
     75   /**
     76    * The group of {@link Property}'s that match.
     77    */
     78   private static final class PropertyGroup {
     79     private final List<Property> m_properties = Lists.newArrayList();
     80 
     81     ////////////////////////////////////////////////////////////////////////////
     82     //
     83     // Constructor
     84     //
     85     ////////////////////////////////////////////////////////////////////////////
     86     public PropertyGroup(Property property) {
     87       m_properties.add(property);
     88     }
     89 
     90     ////////////////////////////////////////////////////////////////////////////
     91     //
     92     // Access
     93     //
     94     ////////////////////////////////////////////////////////////////////////////
     95     /**
     96      * @return <code>true</code> if new matched {@link Property} from given array was added.
     97      */
     98     public boolean add(Property[] properties) {
     99       for (Property property : properties) {
    100         if (add(property)) {
    101           return true;
    102         }
    103       }
    104       // no match
    105       return false;
    106     }
    107 
    108     /**
    109      * @return the composite {@link Property} for this group.
    110      */
    111     public Property getCompositeProperty() {
    112       Property properties[] = m_properties.toArray(new Property[m_properties.size()]);
    113       return properties[0].getComposite(properties);
    114     }
    115 
    116     ////////////////////////////////////////////////////////////////////////////
    117     //
    118     // Internal
    119     //
    120     ////////////////////////////////////////////////////////////////////////////
    121     /**
    122      * @return <code>true</code> if given {@link Property} matches and was added.
    123      */
    124     private boolean add(Property property) {
    125       Property example = m_properties.get(0);
    126       if (example.getClass() == property.getClass()
    127           && example.getTitle().equals(property.getTitle())
    128           && PropertyManager.getCategory(example) == PropertyManager.getCategory(property)) {
    129         m_properties.add(property);
    130         return true;
    131       }
    132       // no match
    133       return false;
    134     }
    135   }
    136 }
    137