1 package org
.argeo
.cms
.ui
.util
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.net
.MalformedURLException
;
7 import java
.net
.URLEncoder
;
8 import java
.nio
.charset
.StandardCharsets
;
9 import java
.util
.HashMap
;
11 import java
.util
.StringTokenizer
;
13 import javax
.jcr
.Node
;
14 import javax
.jcr
.RepositoryException
;
15 import javax
.servlet
.http
.HttpServletRequest
;
17 import org
.argeo
.api
.NodeConstants
;
18 import org
.argeo
.api
.NodeUtils
;
19 import org
.argeo
.cms
.ui
.CmsConstants
;
20 import org
.argeo
.cms
.ui
.CmsView
;
21 import org
.argeo
.eclipse
.ui
.Selected
;
22 import org
.argeo
.eclipse
.ui
.specific
.EclipseUiSpecificUtils
;
23 import org
.argeo
.jcr
.JcrException
;
24 import org
.argeo
.jcr
.JcrUtils
;
25 import org
.eclipse
.rap
.rwt
.RWT
;
26 import org
.eclipse
.rap
.rwt
.service
.ResourceManager
;
27 import org
.eclipse
.swt
.SWT
;
28 import org
.eclipse
.swt
.events
.SelectionListener
;
29 import org
.eclipse
.swt
.graphics
.Image
;
30 import org
.eclipse
.swt
.graphics
.ImageData
;
31 import org
.eclipse
.swt
.graphics
.Point
;
32 import org
.eclipse
.swt
.layout
.FormAttachment
;
33 import org
.eclipse
.swt
.layout
.FormData
;
34 import org
.eclipse
.swt
.layout
.GridData
;
35 import org
.eclipse
.swt
.layout
.GridLayout
;
36 import org
.eclipse
.swt
.layout
.RowData
;
37 import org
.eclipse
.swt
.layout
.RowLayout
;
38 import org
.eclipse
.swt
.widgets
.Button
;
39 import org
.eclipse
.swt
.widgets
.Composite
;
40 import org
.eclipse
.swt
.widgets
.Control
;
41 import org
.eclipse
.swt
.widgets
.Display
;
42 import org
.eclipse
.swt
.widgets
.Label
;
43 import org
.eclipse
.swt
.widgets
.Table
;
44 import org
.eclipse
.swt
.widgets
.Text
;
45 import org
.eclipse
.swt
.widgets
.Widget
;
47 /** Static utilities for the CMS framework. */
48 public class CmsUiUtils
implements CmsConstants
{
49 // private final static Log log = LogFactory.getLog(CmsUiUtils.class);
55 /** Sends an event via {@link CmsView#sendEvent(String, Map)}. */
56 public static void sendEventOnSelect(Control control
, String topic
, Map
<String
, Object
> properties
) {
57 SelectionListener listener
= (Selected
) (e
) -> {
58 CmsView
.getCmsView(control
.getParent()).sendEvent(topic
, properties
);
60 if (control
instanceof Button
) {
61 ((Button
) control
).addSelectionListener(listener
);
63 throw new UnsupportedOperationException("Control type " + control
.getClass() + " is not supported.");
67 * Convenience method to sends an event via
68 * {@link CmsView#sendEvent(String, Map)}.
70 public static void sendEventOnSelect(Control control
, String topic
, String key
, Object value
) {
71 Map
<String
, Object
> properties
= new HashMap
<>();
72 properties
.put(key
, value
);
73 sendEventOnSelect(control
, topic
, properties
);
77 * The CMS view related to this display, or null if none is available from this
80 * @deprecated Use {@link CmsView#getCmsView(Composite)} instead.
83 public static CmsView
getCmsView() {
84 // return UiContext.getData(CmsView.class.getName());
85 return CmsView
.getCmsView(Display
.getCurrent().getActiveShell());
88 public static StringBuilder
getServerBaseUrl(HttpServletRequest request
) {
90 URL url
= new URL(request
.getRequestURL().toString());
91 StringBuilder buf
= new StringBuilder();
92 buf
.append(url
.getProtocol()).append("://").append(url
.getHost());
93 if (url
.getPort() != -1)
94 buf
.append(':').append(url
.getPort());
96 } catch (MalformedURLException e
) {
97 throw new IllegalArgumentException("Cannot extract server base URL from " + request
.getRequestURL(), e
);
102 public static String
getDataUrl(Node node
, HttpServletRequest request
) throws RepositoryException
{
104 StringBuilder buf
= getServerBaseUrl(request
);
105 buf
.append(getDataPath(node
));
106 return new URL(buf
.toString()).toString();
107 } catch (MalformedURLException e
) {
108 throw new IllegalArgumentException("Cannot build data URL for " + node
, e
);
112 /** A path in the node repository */
113 public static String
getDataPath(Node node
) throws RepositoryException
{
114 return getDataPath(NodeConstants
.EGO_REPOSITORY
, node
);
117 public static String
getDataPath(String cn
, Node node
) throws RepositoryException
{
118 return NodeUtils
.getDataPath(cn
, node
);
121 /** Clean reserved URL characters for use in HTTP links. */
122 public static String
getDataPathForUrl(Node node
) throws RepositoryException
{
123 return cleanPathForUrl(getDataPath(node
));
126 /** Clean reserved URL characters for use in HTTP links. */
127 public static String
cleanPathForUrl(String path
) throws RepositoryException
{
128 StringTokenizer st
= new StringTokenizer(path
, "/");
129 StringBuilder sb
= new StringBuilder();
130 while (st
.hasMoreElements()) {
132 String encoded
= URLEncoder
.encode(st
.nextToken(), StandardCharsets
.UTF_8
);
133 encoded
= encoded
.replace("+", "%20");
137 return sb
.toString();
140 /** @deprecated Use rowData16px() instead. GridData should not be reused. */
142 public static RowData ROW_DATA_16px
= new RowData(16, 16);
147 public static GridLayout
noSpaceGridLayout() {
148 return noSpaceGridLayout(new GridLayout());
151 public static GridLayout
noSpaceGridLayout(int columns
) {
152 return noSpaceGridLayout(new GridLayout(columns
, false));
155 /** @return the same layout, with spaces removed. */
156 public static GridLayout
noSpaceGridLayout(GridLayout layout
) {
157 layout
.horizontalSpacing
= 0;
158 layout
.verticalSpacing
= 0;
159 layout
.marginWidth
= 0;
160 layout
.marginHeight
= 0;
164 public static GridData
fillAll() {
165 return new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
168 public static GridData
fillWidth() {
169 return grabWidth(SWT
.FILL
, SWT
.FILL
);
172 public static GridData
grabWidth(int horizontalAlignment
, int verticalAlignment
) {
173 return new GridData(horizontalAlignment
, horizontalAlignment
, true, false);
176 public static GridData
fillHeight() {
177 return grabHeight(SWT
.FILL
, SWT
.FILL
);
180 public static GridData
grabHeight(int horizontalAlignment
, int verticalAlignment
) {
181 return new GridData(horizontalAlignment
, horizontalAlignment
, false, true);
187 /** @return the same layout, with margins removed. */
188 public static RowLayout
noMarginsRowLayout(RowLayout rowLayout
) {
189 rowLayout
.marginTop
= 0;
190 rowLayout
.marginBottom
= 0;
191 rowLayout
.marginLeft
= 0;
192 rowLayout
.marginRight
= 0;
196 public static RowLayout
noMarginsRowLayout(int type
) {
197 return noMarginsRowLayout(new RowLayout(type
));
200 public static RowData
rowData16px() {
201 return new RowData(16, 16);
208 public static FormData
coverAll() {
209 FormData fdLabel
= new FormData();
210 fdLabel
.top
= new FormAttachment(0, 0);
211 fdLabel
.left
= new FormAttachment(0, 0);
212 fdLabel
.right
= new FormAttachment(100, 0);
213 fdLabel
.bottom
= new FormAttachment(100, 0);
222 public static <T
extends Widget
> T
style(T widget
, String style
) {
224 return widget
;// does nothing
225 EclipseUiSpecificUtils
.setStyleData(widget
, style
);
226 if (widget
instanceof Control
) {
227 CmsView
.getCmsView((Control
) widget
).applyStyles(widget
);
233 public static <T
extends Widget
> T
style(T widget
, CmsStyle style
) {
234 return style(widget
, style
.toStyleClass());
237 /** Enable markups on widget */
238 public static <T
extends Widget
> T
markup(T widget
) {
239 EclipseUiSpecificUtils
.setMarkupData(widget
);
243 /** Disable markup validation. */
244 public static <T
extends Widget
> T
disableMarkupValidation(T widget
) {
245 EclipseUiSpecificUtils
.setMarkupValidationDisabledData(widget
);
250 * Apply markup and set text on {@link Label}, {@link Button}, {@link Text}.
252 * @param widget the widget to style and to use in order to display text
253 * @param txt the object to display via its <code>toString()</code> method.
254 * This argument should not be null, but if it is null and
255 * assertions are disabled "<null>" is displayed instead; if
256 * assertions are enabled the call will fail.
258 * @see #markup(Widget)
260 public static <T
extends Widget
> T
text(T widget
, Object txt
) {
262 String str
= txt
!= null ? txt
.toString() : "<null>";
264 if (widget
instanceof Label
)
265 ((Label
) widget
).setText(str
);
266 else if (widget
instanceof Button
)
267 ((Button
) widget
).setText(str
);
268 else if (widget
instanceof Text
)
269 ((Text
) widget
).setText(str
);
271 throw new IllegalArgumentException("Unsupported widget type " + widget
.getClass());
275 /** A {@link Label} with markup activated. */
276 public static Label
lbl(Composite parent
, Object txt
) {
277 return text(new Label(parent
, SWT
.NONE
), txt
);
280 /** A read-only {@link Text} whose content can be copy/pasted. */
281 public static Text
txt(Composite parent
, Object txt
) {
282 return text(new Text(parent
, SWT
.NONE
), txt
);
286 public static void setItemHeight(Table table
, int height
) {
287 table
.setData(CmsConstants
.ITEM_HEIGHT
, height
);
290 /** Dispose all children of a Composite */
291 public static void clear(Composite composite
) {
292 if (composite
.isDisposed())
294 for (Control child
: composite
.getChildren())
301 public static Node
getOrAddEmptyFile(Node parent
, Enum
<?
> child
) throws RepositoryException
{
302 if (has(parent
, child
))
303 return child(parent
, child
);
304 return JcrUtils
.copyBytesAsFile(parent
, child
.name(), new byte[0]);
307 public static Node
child(Node parent
, Enum
<?
> en
) throws RepositoryException
{
308 return parent
.getNode(en
.name());
311 public static Boolean
has(Node parent
, Enum
<?
> en
) throws RepositoryException
{
312 return parent
.hasNode(en
.name());
315 public static Node
getOrAdd(Node parent
, Enum
<?
> en
) throws RepositoryException
{
316 return getOrAdd(parent
, en
, null);
319 public static Node
getOrAdd(Node parent
, Enum
<?
> en
, String primaryType
) throws RepositoryException
{
321 return child(parent
, en
);
322 else if (primaryType
== null)
323 return parent
.addNode(en
.name());
325 return parent
.addNode(en
.name(), primaryType
);
329 public static String
img(Node fileNode
, String width
, String height
) {
330 return img(null, fileNode
, width
, height
);
333 public static String
img(String serverBase
, Node fileNode
, String width
, String height
) {
334 // String src = (serverBase != null ? serverBase : "") + NodeUtils.getDataPath(fileNode);
337 src
= (serverBase
!= null ? serverBase
: "") + getDataPathForUrl(fileNode
);
338 } catch (RepositoryException e
) {
339 throw new JcrException("Cannot get URL data path for " + fileNode
, e
);
341 return imgBuilder(src
, width
, height
).append("/>").toString();
344 public static String
img(String src
, String width
, String height
) {
345 return imgBuilder(src
, width
, height
).append("/>").toString();
348 public static String
img(String src
, Point size
) {
349 return img(src
, Integer
.toString(size
.x
), Integer
.toString(size
.y
));
352 public static StringBuilder
imgBuilder(String src
, String width
, String height
) {
353 return new StringBuilder(64).append("<img width='").append(width
).append("' height='").append(height
)
354 .append("' src='").append(src
).append("'");
357 public static String
noImg(Point size
) {
358 ResourceManager rm
= RWT
.getResourceManager();
359 return CmsUiUtils
.img(rm
.getLocation(NO_IMAGE
), size
);
362 public static String
noImg() {
363 return noImg(NO_IMAGE_SIZE
);
366 public static Image
noImage(Point size
) {
367 ResourceManager rm
= RWT
.getResourceManager();
368 InputStream in
= null;
370 in
= rm
.getRegisteredContent(NO_IMAGE
);
371 ImageData id
= new ImageData(in
);
372 ImageData scaled
= id
.scaledTo(size
.x
, size
.y
);
373 Image image
= new Image(Display
.getCurrent(), scaled
);
378 } catch (IOException e
) {
384 /** Lorem ipsum text to be used during development. */
385 public final static String LOREM_IPSUM
= "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
386 + " Etiam eleifend hendrerit sem, ac ultricies massa ornare ac."
387 + " Cras aliquam sodales risus, vitae varius lacus molestie quis."
388 + " Vivamus consequat, leo id lacinia volutpat, eros diam efficitur urna, finibus interdum risus turpis at nisi."
389 + " Curabitur vulputate nulla quis scelerisque fringilla. Integer consectetur turpis id lobortis accumsan."
390 + " Pellentesque commodo turpis ac diam ultricies dignissim."
391 + " Curabitur sit amet dolor volutpat lacus aliquam ornare quis sed velit."
392 + " Integer varius quis est et tristique."
393 + " Suspendisse pharetra porttitor purus, eget condimentum magna."
394 + " Duis vitae turpis eros. Sed tincidunt lacinia rutrum."
395 + " Aliquam velit velit, rutrum ut augue sed, condimentum lacinia augue.";
398 private CmsUiUtils() {