1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.fourthline.cling.support.contentdirectory.ui;
17
18 import org.fourthline.cling.model.action.ActionException;
19 import org.fourthline.cling.model.action.ActionInvocation;
20 import org.fourthline.cling.model.message.UpnpResponse;
21 import org.fourthline.cling.model.meta.Service;
22 import org.fourthline.cling.support.model.BrowseFlag;
23 import org.fourthline.cling.support.model.DIDLContent;
24 import org.fourthline.cling.support.model.SortCriterion;
25 import org.fourthline.cling.support.contentdirectory.callback.Browse;
26 import org.fourthline.cling.model.types.ErrorCode;
27 import org.fourthline.cling.support.model.container.Container;
28 import org.fourthline.cling.support.model.item.Item;
29
30 import java.util.logging.Logger;
31
32 import javax.swing.tree.MutableTreeNode;
33 import javax.swing.tree.DefaultTreeModel;
34 import javax.swing.tree.DefaultMutableTreeNode;
35 import javax.swing.SwingUtilities;
36 import java.util.ArrayList;
37 import java.util.List;
38
39
40
41
42
43
44 public abstract class ContentBrowseActionCallback extends Browse {
45
46 private static Logger log = Logger.getLogger(ContentBrowseActionCallback.class.getName());
47
48 final protected DefaultTreeModel treeModel;
49 final protected DefaultMutableTreeNode treeNode;
50
51 public ContentBrowseActionCallback(Service service, DefaultTreeModel treeModel, DefaultMutableTreeNode treeNode) {
52 super(service, ((Container) treeNode.getUserObject()).getId(), BrowseFlag.DIRECT_CHILDREN, "*", 0, null, new SortCriterion(true, "dc:title"));
53 this.treeModel = treeModel;
54 this.treeNode = treeNode;
55 }
56
57 public ContentBrowseActionCallback(Service service, DefaultTreeModel treeModel, DefaultMutableTreeNode treeNode,
58 String filter, long firstResult, long maxResults, SortCriterion... orderBy) {
59 super(service, ((Container) treeNode.getUserObject()).getId(), BrowseFlag.DIRECT_CHILDREN, filter, firstResult, maxResults, orderBy);
60 this.treeModel = treeModel;
61 this.treeNode = treeNode;
62 }
63
64 public DefaultTreeModel getTreeModel() {
65 return treeModel;
66 }
67
68 public DefaultMutableTreeNode getTreeNode() {
69 return treeNode;
70 }
71
72 public void received(final ActionInvocation actionInvocation, DIDLContent didl) {
73 log.fine("Received browse action DIDL descriptor, creating tree nodes");
74 final List<DefaultMutableTreeNode> childNodes = new ArrayList<>();
75
76 try {
77
78
79 for (Container childContainer : didl.getContainers()) {
80 DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(childContainer) {
81 @Override
82 public boolean isLeaf() {
83 return false;
84
85
86
87
88
89
90
91
92
93
94 }
95 };
96 childNodes.add(childNode);
97 }
98
99
100 for (Item childItem : didl.getItems()) {
101 DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(childItem) {
102 @Override
103 public boolean isLeaf() {
104 return true;
105 }
106 };
107 childNodes.add(childNode);
108 }
109
110 } catch (Exception ex) {
111 log.fine("Creating DIDL tree nodes failed: " + ex);
112 actionInvocation.setFailure(
113 new ActionException(ErrorCode.ACTION_FAILED, "Can't create tree child nodes: " + ex, ex)
114 );
115 failure(actionInvocation, null);
116 }
117
118 SwingUtilities.invokeLater(new Runnable() {
119 public void run() {
120 updateTreeModel(childNodes);
121 }
122 });
123 }
124
125 public void updateStatus(final Status status) {
126 SwingUtilities.invokeLater(new Runnable() {
127 public void run() {
128 updateStatusUI(status, treeNode, treeModel);
129 }
130 });
131 }
132
133 @Override
134 public void failure(ActionInvocation invocation, UpnpResponse operation, final String defaultMsg) {
135 SwingUtilities.invokeLater(new Runnable() {
136 public void run() {
137 failureUI(defaultMsg);
138 }
139 });
140 }
141
142 protected void updateTreeModel(final List<DefaultMutableTreeNode> childNodes) {
143 log.fine("Adding nodes to tree: " + childNodes.size());
144
145 removeChildren();
146
147
148 for (DefaultMutableTreeNode childNode : childNodes) {
149 insertChild(childNode);
150 }
151 }
152
153 protected void removeChildren() {
154 treeNode.removeAllChildren();
155 treeModel.nodeStructureChanged(treeNode);
156 }
157
158 protected void insertChild(MutableTreeNode childNode) {
159 int index = treeNode.getChildCount() <= 0 ? 0 : treeNode.getChildCount();
160 treeModel.insertNodeInto(childNode, treeNode, index);
161 }
162
163 public abstract void updateStatusUI(Status status, DefaultMutableTreeNode treeNode, DefaultTreeModel treeModel);
164
165 public abstract void failureUI(String failureMessage);
166 }