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