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 * <p>
39 * This interface has to be implemented by a Sling Model class. The adaptables
40 * should be {@link org.apache.sling.api.SlingHttpServletRequest} and {@link org.apache.sling.api.resource.Resource}.
41 * </p>
42 */
43 @ConsumerType
44 public abstract class LinkType {
45
46 /**
47 * @return Link type ID (is stored as identifier in repository)
48 */
49 @JsonProperty("linkType")
50 public abstract @NotNull String getId();
51
52 /**
53 * @return Link type label (displayed in link dialogs)
54 */
55 @JsonIgnore
56 public @NotNull String getLabel() {
57 return getId();
58 }
59
60 /**
61 * @return Name of the property in which the primary link reference is stored
62 */
63 @JsonIgnore
64 public abstract @Nullable String getPrimaryLinkRefProperty();
65
66 /**
67 * Checks whether a link reference can be handled by this link type
68 * @param linkRequest Link reference
69 * @return true if this link type can handle the given link reference
70 */
71 public boolean accepts(@NotNull LinkRequest linkRequest) {
72 ValueMap props = linkRequest.getResourceProperties();
73 // check for matching link type ID in link resource
74 String linkTypeId = props.get(LinkNameConstants.PN_LINK_TYPE, String.class);
75 if (StringUtils.isNotEmpty(linkTypeId)) {
76 return StringUtils.equals(linkTypeId, getId());
77 }
78 // if not link type is set at all check if link ref attribute contains a valid link
79 // or a link reference is given with auto-detection of it's type
80 else {
81 String propertyName = getPrimaryLinkRefProperty();
82 String linkRef = null;
83 if (propertyName != null) {
84 linkRef = props.get(propertyName, String.class);
85 }
86 if (linkRef == null) {
87 linkRef = linkRequest.getReference();
88 }
89 if (linkRef != null) {
90 return accepts(linkRef);
91 }
92 return false;
93 }
94 }
95
96 /**
97 * Checks whether a link reference string can be handled by this link type
98 * @param linkRef Link reference string
99 * @return true if this link type can handle the given link reference
100 */
101 public abstract boolean accepts(@NotNull String linkRef);
102
103 /**
104 * Resolves a link
105 * @param link Link metadata
106 * @return Resolved link metadata. Never null.
107 */
108 public abstract @NotNull Link resolveLink(@NotNull Link link);
109
110 /**
111 * Granite UI component resource type to be used for editing this link type's properties in edit dialog.
112 * @return Granite UI component resource type or null, if none is available
113 */
114 @JsonIgnore
115 public @Nullable String getEditComponentResourceType() {
116 return null;
117 }
118
119 /**
120 * Returns true if a RTE plugin is available for this link type. If not, it is not possible to select
121 * this link type in the rich text editor.
122 * @return true if a RTE plugin is available.
123 */
124 @JsonIgnore
125 public boolean hasRichTextPlugin() {
126 return false;
127 }
128
129 }