Skip to content

Commit c2fd157

Browse files
Enhance documentation for IconsProvider and related classes with detailed descriptions and usage examples
1 parent e7786a0 commit c2fd157

File tree

5 files changed

+504
-5
lines changed

5 files changed

+504
-5
lines changed

platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractFontIconsProvider.java

Lines changed: 116 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,80 @@
2727
import java.util.Properties;
2828

2929
/**
30-
* IconsProvider for Fonts Icons
30+
* Abstract base class for IconsProvider implementations that serve font-based icons.
31+
* This class provides common functionality for loading and managing icon sets from font libraries
32+
* such as FontAwesome, Material Icons, or other web font icon systems.
3133
*
32-
* @author Mario
34+
* <p>Font icons are lightweight, scalable, and customizable through CSS. This provider manages
35+
* the mapping between logical icon names and their internal font class names or Unicode values.</p>
36+
*
37+
* <p>Subclasses must implement {@link #getNamesMapping()} to provide a Properties object
38+
* that maps logical icon names to their internal font-specific identifiers.</p>
39+
*
40+
* <p>The initialization process:</p>
41+
* <ul>
42+
* <li>Loads icon name mappings from the Properties returned by getNamesMapping()</li>
43+
* <li>Creates Icon objects with IconType.FONT for each mapping</li>
44+
* <li>Stores icons in an internal cache for quick retrieval</li>
45+
* <li>Logs the installation progress for debugging</li>
46+
* </ul>
47+
*
48+
* <p>Example implementation:</p>
49+
* <pre>{@code
50+
* @Component
51+
* public class FontAwesomeProvider extends AbstractFontIconsProvider {
52+
*
53+
* @Override
54+
* public Properties getNamesMapping() {
55+
* Properties props = new Properties();
56+
* props.setProperty("save", "fa-save");
57+
* props.setProperty("edit", "fa-edit");
58+
* props.setProperty("delete", "fa-trash");
59+
* return props;
60+
* }
61+
* }
62+
* }</pre>
63+
*
64+
* @author Mario A. Serrano Leones
65+
* @see IconsProvider
66+
* @see Icon
67+
* @see IconType
3368
*/
3469
public abstract class AbstractFontIconsProvider implements IconsProvider {
3570

71+
/**
72+
* Internal cache storing all loaded icons by their logical name.
73+
*/
3674
private final Map<String, Icon> icons = new HashMap<>();
75+
76+
/**
77+
* Logging service for reporting icon loading progress and issues.
78+
*/
3779
private final LoggingService logger = new SLF4JLoggingService(getClass());
3880

81+
/**
82+
* Constructs a new AbstractFontIconsProvider and automatically initializes
83+
* the icon mappings by calling {@link #init()}.
84+
*/
3985
public AbstractFontIconsProvider() {
4086
init();
4187
}
4288

89+
/**
90+
* Initializes the icon provider by loading all icon mappings.
91+
* This method retrieves the Properties from {@link #getNamesMapping()},
92+
* iterates through all entries, and creates Icon objects for each mapping.
93+
*
94+
* <p>The initialization process:</p>
95+
* <ul>
96+
* <li>Obtains the Properties object from the subclass</li>
97+
* <li>Logs the number of icons being installed</li>
98+
* <li>Iterates through each property entry</li>
99+
* <li>Creates a new Icon with IconType.FONT for each mapping</li>
100+
* <li>Stores the icon in the internal cache</li>
101+
* <li>Logs successful completion</li>
102+
* </ul>
103+
*/
43104
private void init() {
44105
Properties names = getNamesMapping();
45106
if (names != null) {
@@ -56,10 +117,26 @@ private void init() {
56117
}
57118
}
58119

120+
/**
121+
* Factory method for creating Icon instances.
122+
* Subclasses can override this method to customize how Icon objects are created,
123+
* for example to add additional metadata or use custom Icon subclasses.
124+
*
125+
* @param name the logical name of the icon (e.g., "save", "edit")
126+
* @param internalName the internal font-specific identifier (e.g., "fa-save", "md-edit")
127+
* @return a new Icon instance configured for font-based rendering
128+
*/
59129
protected Icon newIcon(String name, String internalName) {
60130
return new Icon(name, internalName, IconType.FONT);
61131
}
62132

133+
/**
134+
* Retrieves a font icon by its logical name.
135+
* If the icons cache is empty, triggers initialization automatically.
136+
*
137+
* @param name the logical name of the icon to retrieve
138+
* @return the Icon object if found, or null if not available in this provider
139+
*/
63140
@Override
64141
public Icon getIcon(String name) {
65142
if (icons.isEmpty()) {
@@ -69,13 +146,50 @@ public Icon getIcon(String name) {
69146
return icons.get(name);
70147
}
71148

149+
/**
150+
* Provides the mapping between logical icon names and font-specific identifiers.
151+
* Subclasses must implement this method to supply their icon set configuration.
152+
*
153+
* <p>The Properties object should contain entries where:</p>
154+
* <ul>
155+
* <li>Key: logical icon name used throughout the application (e.g., "save", "edit")</li>
156+
* <li>Value: font-specific CSS class or identifier (e.g., "fa-save", "md-edit")</li>
157+
* </ul>
158+
*
159+
* <p>Example:</p>
160+
* <pre>{@code
161+
* Properties props = new Properties();
162+
* props.setProperty("save", "fa-floppy-disk");
163+
* props.setProperty("edit", "fa-pen-to-square");
164+
* props.setProperty("delete", "fa-trash-can");
165+
* return props;
166+
* }</pre>
167+
*
168+
* @return a Properties object containing icon name mappings, or null if no icons are available
169+
*/
72170
public abstract Properties getNamesMapping();
73171

172+
/**
173+
* Returns all icons provided by this font icon provider.
174+
* The returned list is a copy of the internal cache values.
175+
*
176+
* @return a list containing all font icons managed by this provider
177+
*/
74178
@Override
75179
public List<Icon> getAll() {
76180
return new ArrayList<>(icons.values());
77181
}
78182

183+
/**
184+
* Manually adds an icon to this provider's cache.
185+
* This method allows runtime addition of icons without requiring them to be
186+
* defined in the Properties returned by {@link #getNamesMapping()}.
187+
*
188+
* <p>Useful for dynamically registering icons or overriding existing ones.</p>
189+
*
190+
* @param name the logical name for the icon
191+
* @param icon the Icon object to register
192+
*/
79193
public void addIcon(String name, Icon icon) {
80194
icons.put(name, icon);
81195
}

platform/ui/ui-shared/src/main/java/tools/dynamia/ui/icons/AbstractIconsProvider.java

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,107 @@
2929
import java.util.Map;
3030

3131
/**
32+
* Abstract base class for IconsProvider implementations that serve image-based icons.
33+
* This class provides common functionality for loading and managing icon sets from file resources
34+
* such as PNG, SVG, GIF, or other image formats stored in the classpath.
35+
*
36+
* <p>Image-based icons are loaded from a conventional directory structure under the classpath:
37+
* {@code classpath:web/{prefix}/16/*.{extension}}. The provider scans this directory at initialization
38+
* and automatically registers all icons found.</p>
39+
*
40+
* <p>Subclasses must implement two methods to configure the icon location:</p>
41+
* <ul>
42+
* <li>{@link #getPrefix()}: Defines the subdirectory name under web/ where icons are located</li>
43+
* <li>{@link #getExtension()}: Specifies the file extension of the icon images</li>
44+
* </ul>
45+
*
46+
* <p>The initialization process:</p>
47+
* <ul>
48+
* <li>Constructs the classpath pattern using prefix and extension</li>
49+
* <li>Scans the directory for matching resources</li>
50+
* <li>Creates Icon objects for each found resource</li>
51+
* <li>Caches icons in an internal map for quick retrieval</li>
52+
* <li>Logs the installation progress and any errors</li>
53+
* </ul>
54+
*
55+
* <p>Example implementation:</p>
56+
* <pre>{@code
57+
* @Component
58+
* public class SilkIconsProvider extends AbstractIconsProvider {
59+
*
60+
* @Override
61+
* public String getPrefix() {
62+
* return "silk"; // Icons in classpath:web/silk/16/*.png
63+
* }
64+
*
65+
* @Override
66+
* public String getExtension() {
67+
* return "png";
68+
* }
69+
* }
70+
* }</pre>
71+
*
72+
* <p>Expected directory structure:</p>
73+
* <pre>
74+
* src/main/resources/
75+
* web/
76+
* silk/ (prefix)
77+
* 16/ (fixed size directory)
78+
* save.png (icon files with extension)
79+
* edit.png
80+
* delete.png
81+
* </pre>
3282
*
3383
* @author Mario A. Serrano Leones
84+
* @see IconsProvider
85+
* @see Icon
86+
* @see IconType
3487
*/
3588
public abstract class AbstractIconsProvider implements IconsProvider {
3689

90+
/**
91+
* Logging service for reporting icon loading progress and errors.
92+
*/
3793
private final LoggingService logger = new SLF4JLoggingService(getClass());
94+
95+
/**
96+
* Internal cache storing all loaded icons by their name (without extension).
97+
*/
3898
private final Map<String, Icon> icons = new HashMap<>();
99+
100+
/**
101+
* List containing all loaded icons for quick retrieval.
102+
*/
39103
private final List<Icon> all = new ArrayList<>();
40104

105+
/**
106+
* Constructs a new AbstractIconsProvider and automatically initializes
107+
* the icon set by scanning the classpath directory.
108+
*/
41109
public AbstractIconsProvider() {
42110
init();
43111
}
44112

113+
/**
114+
* Initializes the icon provider by scanning and loading icon resources from the classpath.
115+
* This method builds the resource path using the prefix and extension provided by subclasses,
116+
* scans for matching resources, and creates Icon objects for each found file.
117+
*
118+
* <p>The scanning process:</p>
119+
* <ul>
120+
* <li>Constructs the classpath pattern: {@code classpath:web/{prefix}/16/*.{extension}}</li>
121+
* <li>Logs the installation path for debugging</li>
122+
* <li>Uses IOUtils to scan for matching resources</li>
123+
* <li>Warns if no icons are found in the directory</li>
124+
* <li>Iterates through found resources and extracts icon names from filenames</li>
125+
* <li>Creates Icon objects with IconType.IMAGE for each resource</li>
126+
* <li>Stores icons in both the cache map and the complete list</li>
127+
* <li>Logs successful completion or errors</li>
128+
* </ul>
129+
*
130+
* <p>The icon name is derived from the filename without its extension.
131+
* For example, {@code save.png} becomes an icon with name {@code "save"}.</p>
132+
*/
45133
private void init() {
46134
String prefix = getPrefix();
47135
String extension = getExtension();
@@ -69,10 +157,51 @@ private void init() {
69157
}
70158
}
71159

160+
/**
161+
* Returns the prefix (subdirectory name) where icons are located under the web/ directory.
162+
* This prefix is used to construct the classpath resource pattern for icon scanning.
163+
*
164+
* <p>The prefix defines the icon set name and should match the directory structure:
165+
* {@code src/main/resources/web/{prefix}/16/}</p>
166+
*
167+
* <p>Examples:</p>
168+
* <ul>
169+
* <li>"silk" for Silk icon set → {@code web/silk/16/*.png}</li>
170+
* <li>"fugue" for Fugue icon set → {@code web/fugue/16/*.png}</li>
171+
* <li>"custom" for custom icons → {@code web/custom/16/*.svg}</li>
172+
* </ul>
173+
*
174+
* @return the prefix (subdirectory name) for the icon set
175+
*/
72176
public abstract String getPrefix();
73177

178+
/**
179+
* Returns the file extension for icon image files (without the leading dot).
180+
* This extension is used to filter icon resources during directory scanning.
181+
*
182+
* <p>Common extensions include:</p>
183+
* <ul>
184+
* <li>"png" for PNG images (most common)</li>
185+
* <li>"svg" for SVG vector graphics</li>
186+
* <li>"gif" for GIF images</li>
187+
* <li>"jpg" or "jpeg" for JPEG images</li>
188+
* </ul>
189+
*
190+
* @return the file extension without the leading dot (e.g., "png", "svg", "gif")
191+
*/
74192
public abstract String getExtension();
75193

194+
/**
195+
* Retrieves an image icon by its logical name.
196+
* If the icons cache is empty, triggers initialization automatically.
197+
*
198+
* <p>The name should match the filename (without extension) of an icon in the
199+
* configured directory. For example, if {@code save.png} exists in the icon directory,
200+
* use "save" as the name parameter.</p>
201+
*
202+
* @param name the logical name of the icon (filename without extension)
203+
* @return the Icon object if found, or null if not available in this provider
204+
*/
76205
@Override
77206
public Icon getIcon(String name) {
78207
if (icons.isEmpty()) {
@@ -81,6 +210,12 @@ public Icon getIcon(String name) {
81210
return icons.get(name);
82211
}
83212

213+
/**
214+
* Returns all image icons provided by this icon provider.
215+
* The returned list contains all icons discovered during initialization.
216+
*
217+
* @return a list containing all image icons managed by this provider
218+
*/
84219
@Override
85220
public List<Icon> getAll() {
86221
return all;

0 commit comments

Comments
 (0)