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-2015 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  /**
039   * Mask for the leaf node.
040   */
041  public static final int MODIFIER_LEAF   = 0x01;
042  /**
043   * Mask for the referral node.
044   */
045  public static final int MODIFIER_REFERRAL = 0x02;
046  /**
047   * Mask for the node that has an error.
048   */
049  public static final int MODIFIER_ERROR    = 0x04;
050
051  private final HashMap<String, ImageIcon> iconTable = new HashMap<>();
052  private final HashMap<String, String> pathTable = new HashMap<>();
053  private final HashMap<String, String> descriptionTable = new HashMap<>();
054  private ImageIcon defaultLeafIcon;
055  private ImageIcon suffixIcon;
056  private ImageIcon defaultContainerIcon;
057  private ImageIcon rootNodeIcon;
058  private ImageIcon errorIcon;
059  private ImageIcon errorMaskIcon;
060  private ImageIcon referralMaskIcon;
061
062  /**
063   * The path that contains the icons.
064   */
065  public static final String IMAGE_PATH =
066    "org/opends/guitools/controlpanel/images";
067
068
069  private static final String[] ICON_PATH = {
070    ServerConstants.OC_PERSON,  "ds-user.png",
071    ServerConstants.OC_ORGANIZATION, "ds-folder.png",
072    ServerConstants.OC_ORGANIZATIONAL_UNIT_LC,  "ds-ou.png",
073    ServerConstants.OC_GROUP_OF_NAMES_LC, "ds-group.png",
074    ServerConstants.OC_GROUP_OF_ENTRIES_LC, "ds-group.png",
075    ServerConstants.OC_GROUP_OF_UNIQUE_NAMES_LC,  "ds-group.png",
076    ServerConstants.OC_GROUP_OF_URLS_LC,  "ds-group.png",
077    ServerConstants.OC_VIRTUAL_STATIC_GROUP,  "ds-group.png",
078    "passwordpolicy",   "ds-ppol.png"
079  };
080
081  private static final String[] DESCRIPTION = {
082    ServerConstants.OC_PERSON, INFO_PERSON_ICON_DESCRIPTION.get().toString(),
083    ServerConstants.OC_ORGANIZATION, INFO_ORGANIZATION_ICON_DESCRIPTION.get()
084      .toString(),
085    ServerConstants.OC_ORGANIZATIONAL_UNIT_LC,
086    INFO_ORGANIZATIONAL_UNIT_ICON_DESCRIPTION.get().toString(),
087    ServerConstants.OC_GROUP_OF_NAMES_LC, INFO_STATIC_GROUP_ICON_DESCRIPTION
088      .get().toString(),
089    ServerConstants.OC_GROUP_OF_ENTRIES_LC, INFO_STATIC_GROUP_ICON_DESCRIPTION
090      .get().toString(),
091    ServerConstants.OC_GROUP_OF_UNIQUE_NAMES_LC,
092      INFO_STATIC_GROUP_ICON_DESCRIPTION.get().toString(),
093    ServerConstants.OC_GROUP_OF_URLS_LC, INFO_DYNAMIC_GROUP_ICON_DESCRIPTION
094      .get().toString(),
095    ServerConstants.OC_VIRTUAL_STATIC_GROUP,
096    INFO_VIRTUAL_STATIC_GROUP_ICON_DESCRIPTION.get().toString(),
097    "passwordpolicy", INFO_PASSWORD_POLICY_ICON_DESCRIPTION.get().toString()
098  };
099
100  private final String GENERIC_OBJECT_DESCRIPTION = "Generic entry";
101
102  /** The default constructor. */
103  public IconPool() {
104    // Recopy ICON_PATH in pathTable for fast access
105    for (int i = 0; i < ICON_PATH.length; i = i+2) {
106      pathTable.put(ICON_PATH[i], ICON_PATH[i+1]);
107    }
108    for (int i = 0; i < DESCRIPTION.length; i = i+2) {
109      descriptionTable.put(DESCRIPTION[i], DESCRIPTION[i+1]);
110    }
111  }
112
113
114  /**
115   * If objectClass is null, a default icon is used.
116   * @param objectClasses the objectclass values of the entry for which we want
117   * an icon.
118   * @param modifiers the modifiers associated with the entry (if there was
119   * an error, if it is a referral, etc.).
120   * @return the icon corresponding to the provided object classes and
121   * modifiers.
122   */
123  public ImageIcon getIcon(SortedSet<String> objectClasses, int modifiers) {
124    String key = makeKey(objectClasses, modifiers);
125    ImageIcon result = iconTable.get(key);
126    if (result == null) {
127      result = makeIcon(objectClasses, modifiers);
128      iconTable.put(key, result);
129    }
130    return result;
131  }
132
133  /**
134   * Creates an icon for a given path.
135   * @param path the path of the icon.
136   * @param description the description of the icon
137   * @return the associated ImageIcon.
138   */
139  private ImageIcon createIcon(String path, String description)
140  {
141    ImageIcon icon = Utilities.createImageIcon(path);
142    if (description != null)
143    {
144      icon.setDescription(description);
145      icon.getAccessibleContext().setAccessibleDescription(description);
146    }
147    return icon;
148  }
149
150  /**
151   * Returns the icon associated with a leaf node.
152   * @return the icon associated with a leaf node.
153   */
154  public ImageIcon getDefaultLeafIcon() {
155    if (defaultLeafIcon == null) {
156      defaultLeafIcon = createIcon(IMAGE_PATH + "/ds-generic.png",
157          GENERIC_OBJECT_DESCRIPTION);
158    }
159    return defaultLeafIcon;
160  }
161
162
163  /**
164   * Returns the icon associated with a container node.
165   * @return the icon associated with a container node.
166   */
167  public ImageIcon getDefaultContainerIcon() {
168    if (defaultContainerIcon == null) {
169      defaultContainerIcon = createIcon(IMAGE_PATH + "/ds-folder.png",
170      "Folder entry");
171    }
172    return defaultContainerIcon;
173  }
174
175  /**
176   * Returns the icon associated with a suffix node.
177   * @return the icon associated with a suffix node.
178   */
179  public ImageIcon getSuffixIcon() {
180    if (suffixIcon == null) {
181      suffixIcon = createIcon(IMAGE_PATH + "/ds-suffix.png",
182      "Suffix entry");
183    }
184    return suffixIcon;
185  }
186
187  /**
188   * Returns the icon associated with a root node.
189   * @return the icon associated with a root node.
190   */
191  public ImageIcon getIconForRootNode() {
192    if (rootNodeIcon == null) {
193      rootNodeIcon = createIcon(IMAGE_PATH + "/ds-directory.png",
194      "Root entry");
195    }
196    return rootNodeIcon;
197  }
198
199  /**
200   * Returns the icon associated with a node for which an error occurred.
201   * @return the icon associated with a node for which an error occurred.
202   */
203  public ImageIcon getErrorIcon() {
204    if (errorIcon == null) {
205      errorIcon = UIFactory.getImageIcon(UIFactory.IconType.ERROR);
206    }
207    return errorIcon;
208  }
209
210
211  /**
212   * Returns the icon associated with the error mask icon.
213   * @return the icon associated with the error mask icon.
214   */
215  public ImageIcon getErrorMaskIcon() {
216    if (errorMaskIcon == null) {
217      errorMaskIcon = UIFactory.getImageIcon(UIFactory.IconType.ERROR);
218    }
219    return errorMaskIcon;
220  }
221
222
223  /**
224   * Returns the icon associated with the referral mask icon.
225   * @return the icon associated with the referral mask icon.
226   */
227  public ImageIcon getReferralMaskIcon() {
228    if (referralMaskIcon == null) {
229      referralMaskIcon = createIcon(IMAGE_PATH + "/ds-referral.png",
230      "Referral mask");
231    }
232    return referralMaskIcon;
233  }
234
235
236  /**
237   * Returns an icon for a given objectclass applying some modifiers.
238   * @param objectClasses the objectclasses of the entry
239   * @param modifiers the modifiers of the icon (if the entry is inactivated,
240   * if it is a referral...).
241   * @return an icon for a given objectclass applying some modifiers.
242   */
243  private ImageIcon makeIcon(Set<String> objectClasses, int modifiers) {
244    ImageIcon result;
245
246    // Find the icon associated to the object class
247    if (objectClasses == null || objectClasses.isEmpty()) {
248      result = getDefaultContainerIcon();
249    }
250    else {
251      String iconFile = null;
252      for (String value : objectClasses)
253      {
254        iconFile = pathTable.get(value.toLowerCase());
255        if (iconFile != null)
256        {
257          break;
258        }
259      }
260      if (iconFile == null) {
261        if ((modifiers & MODIFIER_LEAF) != 0) {
262          result = getDefaultLeafIcon();
263        }
264        else {
265          result = getDefaultContainerIcon();
266        }
267      }
268      else {
269        String description = null;
270        for (String value : objectClasses)
271        {
272          description = descriptionTable.get(value.toLowerCase());
273          if (description != null)
274          {
275            break;
276          }
277        }
278        if (description == null)
279        {
280          description = GENERIC_OBJECT_DESCRIPTION;
281        }
282        result = createIcon(IMAGE_PATH + "/" + iconFile,
283            description);
284      }
285    }
286
287    // Alter this icon according the modifiers
288    if ((modifiers & MODIFIER_REFERRAL) != 0) {
289      result = getReferralMaskIcon();
290    }
291    if ((modifiers & MODIFIER_ERROR) != 0) {
292      result = getErrorMaskIcon();
293    }
294
295    return result;
296  }
297
298
299  private String makeKey(SortedSet<String> ocValues, int modifiers) {
300    // TODO: verify the performance of IconPool.makeKey()
301    StringBuilder result = new StringBuilder();
302    if(ocValues != null) {
303      result.append(Utilities.getStringFromCollection(ocValues, ""));
304    }
305    result.append(modifiers);
306    return result.toString();
307  }
308
309}