001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2013-2016 ForgeRock AS.
016 */
017package org.opends.guitools.controlpanel.browser;
018
019import java.util.HashMap;
020import java.util.Set;
021import java.util.SortedSet;
022
023import javax.swing.ImageIcon;
024
025import org.opends.guitools.controlpanel.util.Utilities;
026import org.opends.quicksetup.ui.UIFactory;
027import org.opends.server.util.ServerConstants;
028
029import static org.opends.messages.AdminToolMessages.*;
030
031/**
032 * This class is used as a cache containing the icons that are used by the
033 * BrowserController to update the nodes.  It keeps some icons associated with
034 * some entry types, to suffixes, to the root node, etc.
035 */
036public class IconPool {
037
038  /** Mask for the leaf node. */
039  public static final int MODIFIER_LEAF   = 0x01;
040  /** Mask for the referral node. */
041  public static final int MODIFIER_REFERRAL = 0x02;
042  /** Mask for the node that has an error. */
043  public static final int MODIFIER_ERROR    = 0x04;
044
045  private final HashMap<String, ImageIcon> iconTable = new HashMap<>();
046  private final HashMap<String, String> pathTable = new HashMap<>();
047  private final HashMap<String, String> descriptionTable = new HashMap<>();
048  private ImageIcon defaultLeafIcon;
049  private ImageIcon suffixIcon;
050  private ImageIcon defaultContainerIcon;
051  private ImageIcon rootNodeIcon;
052  private ImageIcon errorIcon;
053  private ImageIcon errorMaskIcon;
054  private ImageIcon referralMaskIcon;
055
056  /** The path that contains the icons. */
057  public static final String IMAGE_PATH =
058    "org/opends/guitools/controlpanel/images";
059
060
061  private static final String[] ICON_PATH = {
062    ServerConstants.OC_PERSON,  "ds-user.png",
063    ServerConstants.OC_ORGANIZATION, "ds-folder.png",
064    ServerConstants.OC_ORGANIZATIONAL_UNIT_LC,  "ds-ou.png",
065    ServerConstants.OC_GROUP_OF_NAMES_LC, "ds-group.png",
066    ServerConstants.OC_GROUP_OF_ENTRIES_LC, "ds-group.png",
067    ServerConstants.OC_GROUP_OF_UNIQUE_NAMES_LC,  "ds-group.png",
068    ServerConstants.OC_GROUP_OF_URLS_LC,  "ds-group.png",
069    ServerConstants.OC_VIRTUAL_STATIC_GROUP,  "ds-group.png",
070    "passwordpolicy",   "ds-ppol.png"
071  };
072
073  private static final String[] DESCRIPTION = {
074    ServerConstants.OC_PERSON, INFO_PERSON_ICON_DESCRIPTION.get().toString(),
075    ServerConstants.OC_ORGANIZATION, INFO_ORGANIZATION_ICON_DESCRIPTION.get()
076      .toString(),
077    ServerConstants.OC_ORGANIZATIONAL_UNIT_LC,
078    INFO_ORGANIZATIONAL_UNIT_ICON_DESCRIPTION.get().toString(),
079    ServerConstants.OC_GROUP_OF_NAMES_LC, INFO_STATIC_GROUP_ICON_DESCRIPTION
080      .get().toString(),
081    ServerConstants.OC_GROUP_OF_ENTRIES_LC, INFO_STATIC_GROUP_ICON_DESCRIPTION
082      .get().toString(),
083    ServerConstants.OC_GROUP_OF_UNIQUE_NAMES_LC,
084      INFO_STATIC_GROUP_ICON_DESCRIPTION.get().toString(),
085    ServerConstants.OC_GROUP_OF_URLS_LC, INFO_DYNAMIC_GROUP_ICON_DESCRIPTION
086      .get().toString(),
087    ServerConstants.OC_VIRTUAL_STATIC_GROUP,
088    INFO_VIRTUAL_STATIC_GROUP_ICON_DESCRIPTION.get().toString(),
089    "passwordpolicy", INFO_PASSWORD_POLICY_ICON_DESCRIPTION.get().toString()
090  };
091
092  private final String GENERIC_OBJECT_DESCRIPTION = "Generic entry";
093
094  /** The default constructor. */
095  public IconPool() {
096    // Recopy ICON_PATH in pathTable for fast access
097    for (int i = 0; i < ICON_PATH.length; i = i+2) {
098      pathTable.put(ICON_PATH[i], ICON_PATH[i+1]);
099    }
100    for (int i = 0; i < DESCRIPTION.length; i = i+2) {
101      descriptionTable.put(DESCRIPTION[i], DESCRIPTION[i+1]);
102    }
103  }
104
105
106  /**
107   * If objectClass is null, a default icon is used.
108   * @param objectClasses the objectclass values of the entry for which we want
109   * an icon.
110   * @param modifiers the modifiers associated with the entry (if there was
111   * an error, if it is a referral, etc.).
112   * @return the icon corresponding to the provided object classes and
113   * modifiers.
114   */
115  public ImageIcon getIcon(SortedSet<String> objectClasses, int modifiers) {
116    String key = makeKey(objectClasses, modifiers);
117    ImageIcon result = iconTable.get(key);
118    if (result == null) {
119      result = makeIcon(objectClasses, modifiers);
120      iconTable.put(key, result);
121    }
122    return result;
123  }
124
125  /**
126   * Creates an icon for a given path.
127   * @param path the path of the icon.
128   * @param description the description of the icon
129   * @return the associated ImageIcon.
130   */
131  private ImageIcon createIcon(String path, String description)
132  {
133    ImageIcon icon = Utilities.createImageIcon(path);
134    if (description != null)
135    {
136      icon.setDescription(description);
137      icon.getAccessibleContext().setAccessibleDescription(description);
138    }
139    return icon;
140  }
141
142  /**
143   * Returns the icon associated with a leaf node.
144   * @return the icon associated with a leaf node.
145   */
146  public ImageIcon getDefaultLeafIcon() {
147    if (defaultLeafIcon == null) {
148      defaultLeafIcon = createIcon(IMAGE_PATH + "/ds-generic.png",
149          GENERIC_OBJECT_DESCRIPTION);
150    }
151    return defaultLeafIcon;
152  }
153
154
155  /**
156   * Returns the icon associated with a container node.
157   * @return the icon associated with a container node.
158   */
159  public ImageIcon getDefaultContainerIcon() {
160    if (defaultContainerIcon == null) {
161      defaultContainerIcon = createIcon(IMAGE_PATH + "/ds-folder.png",
162      "Folder entry");
163    }
164    return defaultContainerIcon;
165  }
166
167  /**
168   * Returns the icon associated with a suffix node.
169   * @return the icon associated with a suffix node.
170   */
171  public ImageIcon getSuffixIcon() {
172    if (suffixIcon == null) {
173      suffixIcon = createIcon(IMAGE_PATH + "/ds-suffix.png",
174      "Suffix entry");
175    }
176    return suffixIcon;
177  }
178
179  /**
180   * Returns the icon associated with a root node.
181   * @return the icon associated with a root node.
182   */
183  public ImageIcon getIconForRootNode() {
184    if (rootNodeIcon == null) {
185      rootNodeIcon = createIcon(IMAGE_PATH + "/ds-directory.png",
186      "Root entry");
187    }
188    return rootNodeIcon;
189  }
190
191  /**
192   * Returns the icon associated with a node for which an error occurred.
193   * @return the icon associated with a node for which an error occurred.
194   */
195  public ImageIcon getErrorIcon() {
196    if (errorIcon == null) {
197      errorIcon = UIFactory.getImageIcon(UIFactory.IconType.ERROR);
198    }
199    return errorIcon;
200  }
201
202
203  /**
204   * Returns the icon associated with the error mask icon.
205   * @return the icon associated with the error mask icon.
206   */
207  public ImageIcon getErrorMaskIcon() {
208    if (errorMaskIcon == null) {
209      errorMaskIcon = UIFactory.getImageIcon(UIFactory.IconType.ERROR);
210    }
211    return errorMaskIcon;
212  }
213
214
215  /**
216   * Returns the icon associated with the referral mask icon.
217   * @return the icon associated with the referral mask icon.
218   */
219  public ImageIcon getReferralMaskIcon() {
220    if (referralMaskIcon == null) {
221      referralMaskIcon = createIcon(IMAGE_PATH + "/ds-referral.png",
222      "Referral mask");
223    }
224    return referralMaskIcon;
225  }
226
227
228  /**
229   * Returns an icon for a given objectclass applying some modifiers.
230   * @param objectClasses the objectclasses of the entry
231   * @param modifiers the modifiers of the icon (if the entry is inactivated,
232   * if it is a referral...).
233   * @return an icon for a given objectclass applying some modifiers.
234   */
235  private ImageIcon makeIcon(Set<String> objectClasses, int modifiers) {
236    ImageIcon result;
237
238    // Find the icon associated to the object class
239    if (objectClasses == null || objectClasses.isEmpty()) {
240      result = getDefaultContainerIcon();
241    }
242    else {
243      String iconFile = null;
244      for (String value : objectClasses)
245      {
246        iconFile = pathTable.get(value.toLowerCase());
247        if (iconFile != null)
248        {
249          break;
250        }
251      }
252      if (iconFile == null) {
253        if ((modifiers & MODIFIER_LEAF) != 0) {
254          result = getDefaultLeafIcon();
255        }
256        else {
257          result = getDefaultContainerIcon();
258        }
259      }
260      else {
261        String description = null;
262        for (String value : objectClasses)
263        {
264          description = descriptionTable.get(value.toLowerCase());
265          if (description != null)
266          {
267            break;
268          }
269        }
270        if (description == null)
271        {
272          description = GENERIC_OBJECT_DESCRIPTION;
273        }
274        result = createIcon(IMAGE_PATH + "/" + iconFile,
275            description);
276      }
277    }
278
279    // Alter this icon according the modifiers
280    if ((modifiers & MODIFIER_REFERRAL) != 0) {
281      result = getReferralMaskIcon();
282    }
283    if ((modifiers & MODIFIER_ERROR) != 0) {
284      result = getErrorMaskIcon();
285    }
286
287    return result;
288  }
289
290
291  private String makeKey(SortedSet<String> ocValues, int modifiers) {
292    // TODO: verify the performance of IconPool.makeKey()
293    StringBuilder result = new StringBuilder();
294    if(ocValues != null) {
295      result.append(Utilities.getStringFromCollection(ocValues, ""));
296    }
297    result.append(modifiers);
298    return result.toString();
299  }
300
301}