1 /*
   2  * Copyright (c) 2012, 2014, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 package com.oracle.javafx.scenebuilder.kit.editor.panel.hierarchy;
  33 
  34 import com.oracle.javafx.scenebuilder.kit.editor.panel.hierarchy.AbstractHierarchyPanelController.DisplayOption;
  35 import static com.oracle.javafx.scenebuilder.kit.editor.panel.hierarchy.AbstractHierarchyPanelController.DisplayOption.FXID;
  36 import static com.oracle.javafx.scenebuilder.kit.editor.panel.hierarchy.AbstractHierarchyPanelController.DisplayOption.INFO;
  37 import static com.oracle.javafx.scenebuilder.kit.editor.panel.hierarchy.AbstractHierarchyPanelController.DisplayOption.NODEID;
  38 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
  39 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask;
  40 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask.Accessory;
  41 import com.oracle.javafx.scenebuilder.kit.metadata.util.PropertyName;
  42 import java.net.URL;
  43 import java.util.List;
  44 import java.util.Objects;
  45 import javafx.scene.image.Image;
  46 
  47 /**
  48  * Object representing the data contained within the hierarchy TreeItems.
  49  *
  50  * @treatAsPrivate
  51  */
  52 public class HierarchyItem {
  53 
  54     protected DesignHierarchyMask mask;
  55 
  56     /**
  57      * Creates a hierarchy item. Empty constructor used by the HierarchyItem
  58      * subclasses.
  59      */
  60     public HierarchyItem() {
  61     }
  62 
  63     /**
  64      * Creates a hierarchy item.
  65      *
  66      * @param fxomObject The FX object represented by this item
  67      */
  68     public HierarchyItem(final FXOMObject fxomObject) {
  69         assert fxomObject != null;
  70         this.mask = new DesignHierarchyMask(fxomObject);
  71     }
  72 
  73     /**
  74      * Returns true if the specified object is a HierarchyItem and it defines
  75      * same non null FXOMObject.
  76      * This method is used to retrieve the cell corresponding to this item.
  77      *
  78      * @param obj the reference object with which to compare
  79      * @return true if this object is the same as the obj argument, false otherwise.
  80      */
  81     @Override
  82     public boolean equals(Object obj) {
  83         if (obj == null) {
  84             return false;
  85         }
  86         if (getClass() != obj.getClass()) {
  87             return false;
  88         }
  89         final HierarchyItem item = (HierarchyItem) obj;
  90         // equals method is overidden in the place holder sub classes.
  91         assert getFxomObject() != null;
  92         return getFxomObject().equals(item.getFxomObject());
  93     }
  94 
  95     @Override
  96     public int hashCode() {
  97         int hash = 5;
  98         hash = 79 * hash + Objects.hashCode(this.mask);
  99         return hash;
 100     }
 101 
 102     /**
 103      * Returns the mask represented by this item.
 104      *
 105      * @return the mask represented by this item.
 106      */
 107     public final DesignHierarchyMask getMask() {
 108         return mask;
 109     }
 110 
 111     /**
 112      * Returns the FX object represented by this item.
 113      *
 114      * @return the FX object represented by this item.
 115      */
 116     public final FXOMObject getFxomObject() {
 117         // Can be null for place holder items
 118         return mask == null ? null : mask.getFxomObject();
 119     }
 120 
 121     /**
 122      * Returns the information of the FX object represented by this item.
 123      *
 124      * @return the information of the FX object represented by this item.
 125      */
 126     public String getDescription() {
 127         // Can be null for place holder items
 128         return mask == null ? null : mask.getDescription();
 129     }
 130 
 131     /**
 132      * Returns the single line information of the FX object represented by this
 133      * item.
 134      *
 135      * @return the information of the FX object represented by this item.
 136      */
 137     public String getSingleLineDescription() {
 138         // Can be null for place holder items
 139         return mask == null ? null : mask.getSingleLineDescription();
 140     }
 141 
 142     /**
 143      * Returns the node ID of the FX object represented by this item.
 144      *
 145      * @return the node ID of the FX object represented by this item.
 146      */
 147     public String getNodeId() {
 148         // Can be null for place holder items
 149         return mask == null ? null : mask.getNodeId();
 150     }
 151 
 152     /**
 153      * Returns the FX ID of the FX object represented by this item.
 154      *
 155      * @return the FX ID of the FX object represented by this item.
 156      */
 157     public String getFxId() {
 158         // Can be null for place holder items
 159         return mask == null ? null : mask.getFxId();
 160     }
 161 
 162     public String getDisplayInfo(final DisplayOption option) {
 163         // Place holder items do not have display info
 164         if (mask == null) {
 165             return null;
 166         }
 167         final Object sceneGraphObject = mask.getFxomObject().getSceneGraphObject();
 168         if (sceneGraphObject == null) {
 169             // For now, handle display label for scenegraph objects only
 170             return null;
 171         }
 172         String info = null;
 173         switch (option) {
 174             case INFO:
 175                 info = getSingleLineDescription();
 176                 break;
 177             case FXID:
 178                 info = getFxId();
 179                 break;
 180             case NODEID:
 181                 info = getNodeId();
 182                 break;
 183         }
 184         return info;
 185     }
 186 
 187     public PropertyName getPropertyNameForDisplayInfo(final DisplayOption option) {
 188         assert mask != null;
 189         PropertyName propertyName = null;
 190         switch (option) {
 191             case INFO:
 192                 propertyName = mask.getPropertyNameForDescription();
 193                 break;
 194             case NODEID:
 195                 propertyName = new PropertyName("id");
 196                 break;
 197             default:
 198                 assert false;
 199         }
 200         return propertyName;
 201     }
 202 
 203     public boolean isResourceKey(final DisplayOption option) {
 204         // Place holder items do not have display info
 205         if (mask == null) {
 206             return false;
 207         }
 208         return option == INFO && mask.isResourceKey();
 209     }
 210 
 211     public boolean isPlaceHolder() {
 212         return false;
 213     }
 214 
 215     public boolean isEmpty() {
 216         return false;
 217     }
 218 
 219     public boolean isAcceptingSubComponent(final List<FXOMObject> fxomObjects) {
 220         return !isEmpty() && mask.isAcceptingSubComponent(fxomObjects);
 221     }
 222 
 223     public boolean isAcceptingAccessory(Accessory accessory, FXOMObject fxomObject) {
 224         return !isEmpty()
 225                 && mask.isAcceptingAccessory(accessory, fxomObject)
 226                 && mask.getAccessory(accessory) == null;
 227     }
 228 
 229     public boolean hasDisplayInfo(final DisplayOption option) {
 230         // Item has display info if we are not on place holder and :
 231         // - either we display the FX ID
 232         // - or we display the node ID
 233         // - or we display the description and the item defines one
 234         return mask != null
 235                 && (option == FXID
 236                 || option == NODEID
 237                 || (option == INFO && mask.hasDescription()));
 238     }
 239 
 240     public Image getPlaceHolderImage() {
 241         // No place holder
 242         return null;
 243     }
 244 
 245     public String getPlaceHolderInfo() {
 246         // No place holder
 247         return null;
 248     }
 249 
 250     public Image getClassNameIcon() {
 251         assert mask != null;
 252         return mask.getClassNameIcon();
 253     }
 254 
 255     public URL getClassNameIconURL() {
 256         assert mask != null;
 257         return mask.getClassNameIconURL();
 258     }
 259 
 260     public String getClassNameInfo() {
 261         assert mask != null;
 262         return mask.getClassNameInfo();
 263     }
 264 }