Java tutorial
/* * Copyright 2013 Hippo B.V. (http://www.onehippo.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hippoecm.frontend.plugins.richtext.view; import java.nio.charset.Charset; import javax.jcr.ItemNotFoundException; import javax.jcr.NamespaceException; import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.lang.StringUtils; import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.attributes.AjaxRequestAttributes; import org.apache.wicket.model.IModel; import org.apache.wicket.request.Request; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.util.encoding.UrlDecoder; import org.apache.wicket.util.encoding.UrlEncoder; import org.apache.wicket.util.string.*; import org.hippoecm.frontend.model.JcrNodeModel; import org.hippoecm.frontend.plugins.richtext.ILinkDecorator; import org.hippoecm.frontend.plugins.standards.ClassResourceModel; import org.hippoecm.frontend.service.IBrowseService; import org.hippoecm.frontend.session.UserSession; import org.hippoecm.repository.util.JcrUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import static org.hippoecm.repository.api.HippoNodeType.HIPPO_DOCBASE; import static org.hippoecm.repository.api.HippoNodeType.NT_DELETED; import static org.hippoecm.repository.api.HippoNodeType.NT_FACETSELECT; class PreviewLinksBehavior extends AbstractDefaultAjaxBehavior implements ILinkDecorator { private static final long serialVersionUID = 1L; private static final String JS_PREVENT_DEFAULT = "Wicket.Event.fix(event).preventDefault();"; private static final String JS_STOP_EVENT = "Wicket.Event.stop(event);"; private static final Logger log = LoggerFactory.getLogger(PreviewLinksBehavior.class); private final IModel<Node> model; private final IBrowseService browser; /** * When this behavior is used in the context of a diff view, the diffing process already * encodes the urls. So this boolean is to prevent links being double encoded in that case. */ private final boolean encode; PreviewLinksBehavior(final IModel<Node> model, final IBrowseService browser, boolean encode) { this.model = model; this.browser = browser; this.encode = encode; } @Override protected void respond(AjaxRequestTarget target) { Request request = RequestCycle.get().getRequest(); final StringValue linkValue = request.getRequestParameters().getParameterValue("link"); if (linkValue != null) { String link = linkValue.toString(); link = UrlDecoder.QUERY_INSTANCE.decode(link, request.getCharset()); if (browser != null) { Node node = model.getObject(); try { if (node.hasNode(link)) { node = node.getNode(link); if (node.isNodeType(NT_FACETSELECT)) { final String uuid = node.getProperty(HIPPO_DOCBASE).getString(); final Session jcrSession = UserSession.get().getJcrSession(); node = jcrSession.getNodeByIdentifier(uuid); browser.browse(new JcrNodeModel(node)); } } } catch (ItemNotFoundException ex) { log.info("Could not resolve link", ex); } catch (RepositoryException e) { log.error("Error while browing to link", e); } } } } @Override public String internalLink(String link) { final AjaxRequestAttributes attributes = getAttributes(); final Charset charset = RequestCycle.get().getRequest().getCharset(); if (linkExists(link)) { if (encode) { link = UrlEncoder.QUERY_INSTANCE.encode(link, charset); } attributes.getExtraParameters().put("link", link); CharSequence asString = renderAjaxAttributes(getComponent(), attributes); return "href=\"#\" onclick='" + JS_PREVENT_DEFAULT + JS_STOP_EVENT + "Wicket.Ajax.get(" + asString + ");'"; } else { String message = new ClassResourceModel("brokenlink-alert", PreviewLinksBehavior.class).getObject(); return "class=\"brokenlink\" href=\"#\" onclick=\"alert('" + message + "');return false;\""; } } @Override public String externalLink(String link) { return "href=\"" + link + "\" onclick=\"" + JS_STOP_EVENT + "\""; } private boolean linkExists(String linkRelPath) { if (StringUtils.startsWith(linkRelPath, "/")) { // absolute path cannot be an internal link return false; } final Node node = model.getObject(); try { if (node.hasNode(linkRelPath)) { final Node link = node.getNode(linkRelPath); final String docbase = JcrUtils.getStringProperty(link, HIPPO_DOCBASE, null); if (docbase != null) { final Node target = UserSession.get().getJcrSession().getNodeByIdentifier(docbase); return !target.getNode(target.getName()).isNodeType(NT_DELETED); } } } catch (ItemNotFoundException | NamespaceException | IllegalArgumentException ignored) { log.debug("Ignoring exception while checking that link '{}' exists and assume it does not exist", linkRelPath, ignored); } catch (RepositoryException e) { log.error("Error while checking internal link existence", e); } return false; } }