1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.support.contentdirectory.callback;
17
18 import org.fourthline.cling.controlpoint.ActionCallback;
19 import org.fourthline.cling.model.action.ActionException;
20 import org.fourthline.cling.model.action.ActionInvocation;
21 import org.fourthline.cling.model.meta.Service;
22 import org.fourthline.cling.model.types.ErrorCode;
23 import org.fourthline.cling.model.types.UnsignedIntegerFourBytes;
24 import org.fourthline.cling.support.contentdirectory.DIDLParser;
25 import org.fourthline.cling.support.model.BrowseFlag;
26 import org.fourthline.cling.support.model.BrowseResult;
27 import org.fourthline.cling.support.model.DIDLContent;
28 import org.fourthline.cling.support.model.SortCriterion;
29
30 import java.util.logging.Logger;
31
32
33
34
35
36
37 public abstract class Browse extends ActionCallback {
38
39 public static final String CAPS_WILDCARD = "*";
40
41 public enum Status {
42 NO_CONTENT("No Content"),
43 LOADING("Loading..."),
44 OK("OK");
45
46 private String defaultMessage;
47
48 Status(String defaultMessage) {
49 this.defaultMessage = defaultMessage;
50 }
51
52 public String getDefaultMessage() {
53 return defaultMessage;
54 }
55 }
56
57 private static Logger log = Logger.getLogger(Browse.class.getName());
58
59
60
61
62 public Browse(Service service, String containerId, BrowseFlag flag) {
63 this(service, containerId, flag, CAPS_WILDCARD, 0, null);
64 }
65
66
67
68
69 public Browse(Service service, String objectID, BrowseFlag flag,
70 String filter, long firstResult, Long maxResults, SortCriterion... orderBy) {
71
72 super(new ActionInvocation(service.getAction("Browse")));
73
74 log.fine("Creating browse action for object ID: " + objectID);
75
76 getActionInvocation().setInput("ObjectID", objectID);
77 getActionInvocation().setInput("BrowseFlag", flag.toString());
78 getActionInvocation().setInput("Filter", filter);
79 getActionInvocation().setInput("StartingIndex", new UnsignedIntegerFourBytes(firstResult));
80 getActionInvocation().setInput("RequestedCount",
81 new UnsignedIntegerFourBytes(maxResults == null ? getDefaultMaxResults() : maxResults)
82 );
83 getActionInvocation().setInput("SortCriteria", SortCriterion.toString(orderBy));
84 }
85
86 @Override
87 public void run() {
88 updateStatus(Status.LOADING);
89 super.run();
90 }
91
92 public void success(ActionInvocation invocation) {
93 log.fine("Successful browse action, reading output argument values");
94
95 BrowseResult result = new BrowseResult(
96 invocation.getOutput("Result").getValue().toString(),
97 (UnsignedIntegerFourBytes) invocation.getOutput("NumberReturned").getValue(),
98 (UnsignedIntegerFourBytes) invocation.getOutput("TotalMatches").getValue(),
99 (UnsignedIntegerFourBytes) invocation.getOutput("UpdateID").getValue()
100 );
101
102 boolean proceed = receivedRaw(invocation, result);
103
104 if (proceed && result.getCountLong() > 0 && result.getResult().length() > 0) {
105
106 try {
107
108 DIDLParser didlParser = new DIDLParser();
109 DIDLContent didl = didlParser.parse(result.getResult());
110 received(invocation, didl);
111 updateStatus(Status.OK);
112
113 } catch (Exception ex) {
114 invocation.setFailure(
115 new ActionException(ErrorCode.ACTION_FAILED, "Can't parse DIDL XML response: " + ex, ex)
116 );
117 failure(invocation, null);
118 }
119
120 } else {
121 received(invocation, new DIDLContent());
122 updateStatus(Status.NO_CONTENT);
123 }
124 }
125
126
127
128
129
130
131 public long getDefaultMaxResults() {
132 return 999;
133 }
134
135 public boolean receivedRaw(ActionInvocation actionInvocation, BrowseResult browseResult) {
136
137
138
139
140
141
142
143 return true;
144 }
145
146 public abstract void received(ActionInvocation actionInvocation, DIDLContent didl);
147 public abstract void updateStatus(Status status);
148
149 }