0
# Portlet Framework
1
2
Complete portlet framework implementation including containers, request/response handling, asset management, document library functionality, and custom fields (expando) support for the Liferay portal platform.
3
4
## Capabilities
5
6
### Core Portlet Framework
7
8
Foundation portlet framework providing complete portlet container implementation with lifecycle management.
9
10
```java { .api }
11
/**
12
* Base portlet implementation providing common portlet functionality
13
*/
14
public abstract class BasePortlet implements Portlet {
15
16
/**
17
* Initializes the portlet with portal-specific configuration
18
* @param portletConfig portlet configuration
19
* @throws PortletException if initialization fails
20
*/
21
@Override
22
public void init(PortletConfig portletConfig) throws PortletException;
23
24
/**
25
* Processes action requests from portlet forms
26
* @param actionRequest portlet action request
27
* @param actionResponse portlet action response
28
* @throws PortletException if action processing fails
29
* @throws IOException if I/O error occurs
30
*/
31
@Override
32
public void processAction(ActionRequest actionRequest, ActionResponse actionResponse)
33
throws PortletException, IOException;
34
35
/**
36
* Renders portlet content for display
37
* @param renderRequest portlet render request
38
* @param renderResponse portlet render response
39
* @throws PortletException if rendering fails
40
* @throws IOException if I/O error occurs
41
*/
42
@Override
43
public void render(RenderRequest renderRequest, RenderResponse renderResponse)
44
throws PortletException, IOException;
45
46
/**
47
* Cleans up portlet resources
48
*/
49
@Override
50
public void destroy();
51
}
52
53
/**
54
* Portlet container managing portlet lifecycle and execution
55
*/
56
public class PortletContainer {
57
58
/**
59
* Deploys portlet application
60
* @param portletApp portlet application descriptor
61
* @throws PortletException if deployment fails
62
*/
63
public void deployPortlet(PortletApp portletApp) throws PortletException;
64
65
/**
66
* Undeploys portlet application
67
* @param portletName portlet name to undeploy
68
* @throws PortletException if undeployment fails
69
*/
70
public void undeployPortlet(String portletName) throws PortletException;
71
72
/**
73
* Gets deployed portlet instance
74
* @param portletName portlet name
75
* @return Portlet instance or null if not found
76
*/
77
public Portlet getPortlet(String portletName);
78
79
/**
80
* Lists all deployed portlets
81
* @return Set of deployed portlet names
82
*/
83
public Set<String> getDeployedPortlets();
84
}
85
```
86
87
### Asset Framework
88
89
Comprehensive asset management system for handling content assets, metadata, and relationships.
90
91
```java { .api }
92
/**
93
* Asset entry representing any content asset in the portal
94
*/
95
public class AssetEntry {
96
97
/**
98
* Gets asset entry ID
99
* @return asset entry ID
100
*/
101
public long getEntryId();
102
103
/**
104
* Gets asset title
105
* @return asset title
106
*/
107
public String getTitle();
108
109
/**
110
* Sets asset title
111
* @param title asset title
112
*/
113
public void setTitle(String title);
114
115
/**
116
* Gets asset description
117
* @return asset description
118
*/
119
public String getDescription();
120
121
/**
122
* Sets asset description
123
* @param description asset description
124
*/
125
public void setDescription(String description);
126
127
/**
128
* Gets asset categories
129
* @return List of asset categories
130
*/
131
public List<AssetCategory> getCategories();
132
133
/**
134
* Gets asset tags
135
* @return List of asset tags
136
*/
137
public List<AssetTag> getTags();
138
}
139
140
/**
141
* Asset service for managing content assets
142
*/
143
public interface AssetEntryService {
144
145
/**
146
* Adds new asset entry
147
* @param className asset class name
148
* @param classPK asset class primary key
149
* @param title asset title
150
* @param description asset description
151
* @param serviceContext service context
152
* @return created AssetEntry
153
* @throws PortalException if creation fails
154
*/
155
AssetEntry addEntry(String className, long classPK, String title, String description,
156
ServiceContext serviceContext) throws PortalException;
157
158
/**
159
* Updates existing asset entry
160
* @param entryId asset entry ID
161
* @param title updated title
162
* @param description updated description
163
* @param serviceContext service context
164
* @return updated AssetEntry
165
* @throws PortalException if update fails
166
*/
167
AssetEntry updateEntry(long entryId, String title, String description,
168
ServiceContext serviceContext) throws PortalException;
169
170
/**
171
* Deletes asset entry
172
* @param entryId asset entry ID
173
* @throws PortalException if deletion fails
174
*/
175
void deleteEntry(long entryId) throws PortalException;
176
177
/**
178
* Searches for asset entries
179
* @param keywords search keywords
180
* @param categoryIds category filter IDs
181
* @param tagNames tag filter names
182
* @return List of matching AssetEntry objects
183
*/
184
List<AssetEntry> searchEntries(String keywords, long[] categoryIds, String[] tagNames);
185
}
186
```
187
188
### Document Library Framework
189
190
Complete document management system with storage backends, version control, and metadata management.
191
192
```java { .api }
193
/**
194
* Document library folder for organizing documents
195
*/
196
public class DLFolder {
197
198
/**
199
* Gets folder ID
200
* @return folder ID
201
*/
202
public long getFolderId();
203
204
/**
205
* Gets folder name
206
* @return folder name
207
*/
208
public String getName();
209
210
/**
211
* Sets folder name
212
* @param name folder name
213
*/
214
public void setName(String name);
215
216
/**
217
* Gets parent folder ID
218
* @return parent folder ID
219
*/
220
public long getParentFolderId();
221
222
/**
223
* Gets folder description
224
* @return folder description
225
*/
226
public String getDescription();
227
}
228
229
/**
230
* Document library file entry representing uploaded documents
231
*/
232
public class DLFileEntry {
233
234
/**
235
* Gets file entry ID
236
* @return file entry ID
237
*/
238
public long getFileEntryId();
239
240
/**
241
* Gets file name
242
* @return file name
243
*/
244
public String getFileName();
245
246
/**
247
* Gets file title
248
* @return file title
249
*/
250
public String getTitle();
251
252
/**
253
* Gets file MIME type
254
* @return MIME type
255
*/
256
public String getMimeType();
257
258
/**
259
* Gets file size in bytes
260
* @return file size
261
*/
262
public long getSize();
263
264
/**
265
* Gets file version
266
* @return version string
267
*/
268
public String getVersion();
269
270
/**
271
* Gets file content as input stream
272
* @return InputStream for file content
273
* @throws IOException if content cannot be accessed
274
*/
275
public InputStream getContentStream() throws IOException;
276
}
277
278
/**
279
* Document library service for managing documents
280
*/
281
public interface DLFileEntryService {
282
283
/**
284
* Adds new file entry
285
* @param folderId parent folder ID
286
* @param fileName file name
287
* @param mimeType MIME type
288
* @param title file title
289
* @param description file description
290
* @param changeLog change log message
291
* @param bytes file content bytes
292
* @param serviceContext service context
293
* @return created DLFileEntry
294
* @throws PortalException if creation fails
295
*/
296
DLFileEntry addFileEntry(long folderId, String fileName, String mimeType,
297
String title, String description, String changeLog, byte[] bytes,
298
ServiceContext serviceContext) throws PortalException;
299
300
/**
301
* Updates file entry content
302
* @param fileEntryId file entry ID
303
* @param fileName updated file name
304
* @param mimeType updated MIME type
305
* @param title updated title
306
* @param description updated description
307
* @param changeLog change log message
308
* @param bytes updated file content
309
* @param serviceContext service context
310
* @return updated DLFileEntry
311
* @throws PortalException if update fails
312
*/
313
DLFileEntry updateFileEntry(long fileEntryId, String fileName, String mimeType,
314
String title, String description, String changeLog, byte[] bytes,
315
ServiceContext serviceContext) throws PortalException;
316
317
/**
318
* Deletes file entry
319
* @param fileEntryId file entry ID
320
* @throws PortalException if deletion fails
321
*/
322
void deleteFileEntry(long fileEntryId) throws PortalException;
323
324
/**
325
* Gets file entries in folder
326
* @param folderId folder ID
327
* @return List of DLFileEntry objects in folder
328
*/
329
List<DLFileEntry> getFileEntries(long folderId);
330
}
331
```
332
333
### Document Storage Backends
334
335
Flexible document storage implementations supporting various storage backends and configurations.
336
337
```java { .api }
338
/**
339
* Abstract document store providing storage backend interface
340
*/
341
public abstract class Store {
342
343
/**
344
* Stores file content with specified key
345
* @param companyId company ID
346
* @param repositoryId repository ID
347
* @param fileName file name
348
* @param versionLabel version label
349
* @param inputStream file content stream
350
* @throws SystemException if storage fails
351
*/
352
public abstract void addFile(long companyId, long repositoryId, String fileName,
353
String versionLabel, InputStream inputStream) throws SystemException;
354
355
/**
356
* Retrieves file content as input stream
357
* @param companyId company ID
358
* @param repositoryId repository ID
359
* @param fileName file name
360
* @param versionLabel version label
361
* @return InputStream for file content
362
* @throws SystemException if retrieval fails
363
*/
364
public abstract InputStream getFileAsStream(long companyId, long repositoryId,
365
String fileName, String versionLabel) throws SystemException;
366
367
/**
368
* Deletes file from storage
369
* @param companyId company ID
370
* @param repositoryId repository ID
371
* @param fileName file name
372
* @param versionLabel version label
373
* @throws SystemException if deletion fails
374
*/
375
public abstract void deleteFile(long companyId, long repositoryId, String fileName,
376
String versionLabel) throws SystemException;
377
378
/**
379
* Checks if file exists in storage
380
* @param companyId company ID
381
* @param repositoryId repository ID
382
* @param fileName file name
383
* @param versionLabel version label
384
* @return true if file exists
385
*/
386
public abstract boolean hasFile(long companyId, long repositoryId, String fileName,
387
String versionLabel);
388
}
389
390
/**
391
* File system storage implementation
392
*/
393
public class FileSystemStore extends Store {
394
// File system-based storage implementation
395
}
396
397
/**
398
* Database storage implementation using BLOB fields
399
*/
400
public class DBStore extends Store {
401
// Database BLOB-based storage implementation
402
}
403
404
/**
405
* Amazon S3 storage implementation
406
*/
407
public class S3Store extends Store {
408
// Amazon S3-based storage implementation
409
}
410
```
411
412
### Expando (Custom Fields) Framework
413
414
Custom fields system allowing dynamic attribute addition to any portal entity.
415
416
```java { .api }
417
/**
418
* Expando table representing custom field container for entity type
419
*/
420
public class ExpandoTable {
421
422
/**
423
* Gets table ID
424
* @return table ID
425
*/
426
public long getTableId();
427
428
/**
429
* Gets table name
430
* @return table name
431
*/
432
public String getName();
433
434
/**
435
* Gets entity class name this table is for
436
* @return entity class name
437
*/
438
public String getClassName();
439
}
440
441
/**
442
* Expando column representing individual custom field definition
443
*/
444
public class ExpandoColumn {
445
446
/**
447
* Gets column ID
448
* @return column ID
449
*/
450
public long getColumnId();
451
452
/**
453
* Gets column name
454
* @return column name
455
*/
456
public String getName();
457
458
/**
459
* Gets column data type
460
* @return data type constant
461
*/
462
public int getType();
463
464
/**
465
* Gets default value for column
466
* @return default value
467
*/
468
public Serializable getDefaultValue();
469
470
/**
471
* Sets default value for column
472
* @param defaultValue default value
473
*/
474
public void setDefaultValue(Serializable defaultValue);
475
}
476
477
/**
478
* Expando value representing actual custom field data for entity instance
479
*/
480
public class ExpandoValue {
481
482
/**
483
* Gets value ID
484
* @return value ID
485
*/
486
public long getValueId();
487
488
/**
489
* Gets entity class primary key this value belongs to
490
* @return entity class primary key
491
*/
492
public long getClassPK();
493
494
/**
495
* Gets column ID this value is for
496
* @return column ID
497
*/
498
public long getColumnId();
499
500
/**
501
* Gets the stored value
502
* @return stored value
503
*/
504
public Serializable getValue();
505
506
/**
507
* Sets the stored value
508
* @param value value to store
509
*/
510
public void setValue(Serializable value);
511
}
512
513
/**
514
* Expando service for managing custom fields
515
*/
516
public interface ExpandoValueService {
517
518
/**
519
* Adds custom field value for entity
520
* @param className entity class name
521
* @param tableName table name
522
* @param columnName column name
523
* @param classPK entity primary key
524
* @param value value to store
525
* @return created ExpandoValue
526
* @throws PortalException if creation fails
527
*/
528
ExpandoValue addValue(String className, String tableName, String columnName,
529
long classPK, Serializable value) throws PortalException;
530
531
/**
532
* Gets custom field value for entity
533
* @param className entity class name
534
* @param tableName table name
535
* @param columnName column name
536
* @param classPK entity primary key
537
* @return ExpandoValue or null if not found
538
*/
539
ExpandoValue getValue(String className, String tableName, String columnName, long classPK);
540
541
/**
542
* Updates custom field value
543
* @param className entity class name
544
* @param tableName table name
545
* @param columnName column name
546
* @param classPK entity primary key
547
* @param value new value
548
* @return updated ExpandoValue
549
* @throws PortalException if update fails
550
*/
551
ExpandoValue updateValue(String className, String tableName, String columnName,
552
long classPK, Serializable value) throws PortalException;
553
554
/**
555
* Deletes custom field value
556
* @param className entity class name
557
* @param tableName table name
558
* @param columnName column name
559
* @param classPK entity primary key
560
* @throws PortalException if deletion fails
561
*/
562
void deleteValue(String className, String tableName, String columnName, long classPK)
563
throws PortalException;
564
}
565
```
566
567
## Usage Examples
568
569
**Portlet Development:**
570
571
```java
572
public class CustomPortlet extends BasePortlet {
573
574
@Override
575
public void render(RenderRequest renderRequest, RenderResponse renderResponse)
576
throws PortletException, IOException {
577
578
// Get portlet preferences
579
PortletPreferences preferences = renderRequest.getPreferences();
580
String title = preferences.getValue("title", "Default Title");
581
582
// Set render attributes
583
renderRequest.setAttribute("title", title);
584
renderRequest.setAttribute("data", getPortletData());
585
586
// Forward to JSP
587
PortletRequestDispatcher dispatcher = getPortletContext()
588
.getRequestDispatcher("/html/view.jsp");
589
dispatcher.include(renderRequest, renderResponse);
590
}
591
592
@Override
593
public void processAction(ActionRequest actionRequest, ActionResponse actionResponse)
594
throws PortletException, IOException {
595
596
String action = actionRequest.getParameter("action");
597
598
if ("updateSettings".equals(action)) {
599
// Update portlet preferences
600
PortletPreferences preferences = actionRequest.getPreferences();
601
preferences.setValue("title", actionRequest.getParameter("title"));
602
preferences.store();
603
}
604
}
605
}
606
```
607
608
**Asset Management:**
609
610
```java
611
// Create asset entry for custom content
612
ServiceContext serviceContext = new ServiceContext();
613
serviceContext.setUserId(userId);
614
serviceContext.setScopeGroupId(groupId);
615
616
AssetEntry entry = assetEntryService.addEntry(
617
"com.company.model.CustomContent",
618
customContent.getId(),
619
customContent.getTitle(),
620
customContent.getDescription(),
621
serviceContext
622
);
623
624
// Add categories and tags
625
String[] categoryNames = {"Technology", "Tutorial"};
626
String[] tagNames = {"java", "portlet", "liferay"};
627
assetEntryService.updateEntry(entry.getEntryId(), categoryNames, tagNames);
628
```
629
630
**Document Library Usage:**
631
632
```java
633
// Upload document
634
byte[] fileBytes = FileUtil.getBytes(uploadedFile);
635
DLFileEntry fileEntry = dlFileEntryService.addFileEntry(
636
folderId,
637
uploadedFile.getName(),
638
uploadedFile.getContentType(),
639
"Uploaded Document",
640
"Document uploaded by user",
641
"Initial upload",
642
fileBytes,
643
serviceContext
644
);
645
646
// Download document
647
InputStream contentStream = fileEntry.getContentStream();
648
// Stream content to response
649
```
650
651
**Custom Fields (Expando):**
652
653
```java
654
// Add custom field to User entity
655
expandoValueService.addValue(
656
User.class.getName(),
657
"CUSTOM_FIELDS",
658
"department",
659
user.getUserId(),
660
"Engineering"
661
);
662
663
// Retrieve custom field value
664
ExpandoValue departmentValue = expandoValueService.getValue(
665
User.class.getName(),
666
"CUSTOM_FIELDS",
667
"department",
668
user.getUserId()
669
);
670
671
String department = (String) departmentValue.getValue();
672
```
673
674
## Integration with Portal Framework
675
676
The portlet framework integrates with:
677
678
- **Portal Services** - Access to all portal functionality
679
- **Security Framework** - Permission checking and user context
680
- **Asset Framework** - Content tagging and categorization
681
- **Workflow Engine** - Business process integration
682
- **Search Framework** - Content indexing and search
683
- **Cache Framework** - Performance optimization
684
685
## Error Handling
686
687
Common portlet framework exceptions:
688
689
- **PortletException** - General portlet processing errors
690
- **PortalException** - Portal service operation failures
691
- **SystemException** - System-level errors
692
- **PrincipalException** - Permission and security violations
693
- **DocumentLibraryException** - Document management errors
694
695
Best practices include proper exception handling, resource cleanup, comprehensive logging, and graceful error recovery to maintain portal stability.