1 /*
2 * #%L
3 * wcm.io
4 * %%
5 * Copyright (C) 2014 wcm.io
6 * %%
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * #L%
19 */
20 package io.wcm.handler.link.spi;
21
22 import org.apache.commons.lang3.StringUtils;
23 import org.apache.sling.api.resource.ValueMap;
24 import org.jetbrains.annotations.NotNull;
25 import org.jetbrains.annotations.Nullable;
26 import org.osgi.annotation.versioning.ConsumerType;
27
28 import com.fasterxml.jackson.annotation.JsonIgnore;
29 import com.fasterxml.jackson.annotation.JsonProperty;
30
31 import io.wcm.handler.link.Link;
32 import io.wcm.handler.link.LinkHandler;
33 import io.wcm.handler.link.LinkNameConstants;
34 import io.wcm.handler.link.LinkRequest;
35
36 /**
37 * Defines a link type supported by {@link LinkHandler}.
38 *
39 * <p>
40 * This interface has to be implemented by a Sling Model class. The adaptables
41 * should be {@link org.apache.sling.api.SlingHttpServletRequest} and {@link org.apache.sling.api.resource.Resource}.
42 * </p>
43 */
44 @ConsumerType
45 public abstract class LinkType {
46
47 /**
48 * @return Link type ID (is stored as identifier in repository)
49 */
50 @JsonProperty("linkType")
51 public abstract @NotNull String getId();
52
53 /**
54 * @return Link type label (displayed in link dialogs)
55 */
56 @JsonIgnore
57 public @NotNull String getLabel() {
58 return getId();
59 }
60
61 /**
62 * @return Name of the property in which the primary link reference is stored
63 */
64 @JsonIgnore
65 public abstract @Nullable String getPrimaryLinkRefProperty();
66
67 /**
68 * Checks whether a link reference can be handled by this link type
69 * @param linkRequest Link reference
70 * @return true if this link type can handle the given link reference
71 */
72 public boolean accepts(@NotNull LinkRequest linkRequest) {
73 ValueMap props = linkRequest.getResourceProperties();
74 // check for matching link type ID in link resource
75 String linkTypeId = props.get(LinkNameConstants.PN_LINK_TYPE, String.class);
76 if (StringUtils.isNotEmpty(linkTypeId)) {
77 return StringUtils.equals(linkTypeId, getId());
78 }
79 // if not link type is set at all check if link ref attribute contains a valid link
80 // or a link reference is given with auto-detection of it's type
81 else {
82 String propertyName = getPrimaryLinkRefProperty();
83 String linkRef = null;
84 if (propertyName != null) {
85 linkRef = props.get(propertyName, String.class);
86 }
87 if (linkRef == null) {
88 linkRef = linkRequest.getReference();
89 }
90 if (linkRef != null) {
91 return accepts(linkRef);
92 }
93 return false;
94 }
95 }
96
97 /**
98 * Checks whether a link reference string can be handled by this link type
99 * @param linkRef Link reference string
100 * @return true if this link type can handle the given link reference
101 */
102 public abstract boolean accepts(@NotNull String linkRef);
103
104 /**
105 * Resolves a link
106 * @param link Link metadata
107 * @return Resolved link metadata. Never null.
108 */
109 public abstract @NotNull Link resolveLink(@NotNull Link link);
110
111 /**
112 * Granite UI component resource type to be used for editing this link type's properties in edit dialog.
113 * @return Granite UI component resource type or null, if none is available
114 */
115 @JsonIgnore
116 public @Nullable String getEditComponentResourceType() {
117 return null;
118 }
119
120 /**
121 * Returns true if a RTE plugin is available for this link type. If not, it is not possible to select
122 * this link type in the rich text editor.
123 * @return true if a RTE plugin is available.
124 */
125 @JsonIgnore
126 public boolean hasRichTextPlugin() {
127 return false;
128 }
129
130 }