AbstractSirenConverter.java 11.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.reef.siren.Action
 *  com.adobe.reef.siren.Entity
 *  com.adobe.reef.siren.Link
 *  com.adobe.reef.siren.builder.BuilderException
 *  com.adobe.reef.siren.builder.EntityBuilder
 *  com.adobe.reef.siren.builder.LinkBuilder
 *  org.apache.commons.lang.ArrayUtils
 *  org.apache.jackrabbit.util.ISO8601
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ValueMap
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.rest.converter.siren;

import com.adobe.granite.rest.converter.ResourceConverter;
import com.adobe.granite.rest.converter.ResourceConverterContext;
import com.adobe.granite.rest.converter.ResourceConverterException;
import com.adobe.granite.rest.filter.Filter;
import com.adobe.granite.rest.utils.Resources;
import com.adobe.granite.rest.utils.URIUtils;
import com.adobe.reef.siren.Action;
import com.adobe.reef.siren.Entity;
import com.adobe.reef.siren.Link;
import com.adobe.reef.siren.builder.BuilderException;
import com.adobe.reef.siren.builder.EntityBuilder;
import com.adobe.reef.siren.builder.LinkBuilder;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.ArrayUtils;
import org.apache.jackrabbit.util.ISO8601;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractSirenConverter
implements ResourceConverter<Entity> {
    protected static final String[] PREFIX_ALLOWED_SHORT = new String[]{"dc"};
    protected static final String[] PREFIX_ALLOWED = new String[]{"dc", "cq", "crs", "xmp"};
    public static final String PREFIX_SRN = "srn:";
    protected Logger log;
    protected Resource resource;
    private Collection<Resource> children;
    public static final String REL_SELF = "self";
    public static final String REL_CHILD = "child";
    public static final String REL_CONTENT = "content";
    public static final String REL_NEXT = "next";
    public static final String REL_PREV = "prev";
    public static final String REL_PARENT = "parent";

    public AbstractSirenConverter(Resource resource) {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.resource = resource;
    }

    protected Collection<Resource> listChildren() {
        if (this.children == null) {
            this.children = new LinkedList<Resource>();
            Iterator it = this.resource.listChildren();
            while (it.hasNext()) {
                Resource resource = (Resource)it.next();
                this.children.add(resource);
            }
        }
        return this.children;
    }

    protected boolean isAllowedPrefix(String key, String[] allowedPrefixes) {
        return this.isAllowedPrefix(key, null, allowedPrefixes);
    }

    protected boolean isAllowedPrefix(String key, ResourceConverterContext context, String[] allowedPrefixes) {
        boolean allowed;
        if (key.charAt(0) == '_') {
            return false;
        }
        if (context != null && context.getShowProperties() != null && context.getShowProperties().length > 0 && (allowed = ArrayUtils.contains((Object[])context.getShowProperties(), (Object)key))) {
            return allowed;
        }
        String prefix = "";
        int pos = key.indexOf(58);
        if (pos < 0) {
            return true;
        }
        prefix = key.substring(0, pos);
        for (String p : allowedPrefixes) {
            if (!p.equals(prefix)) continue;
            return true;
        }
        return false;
    }

    protected abstract String[] getClazz();

    protected Map<String, Object> getProperties(ResourceConverterContext context) {
        return this.getProperties(context, false);
    }

    protected Map<String, Object> getProperties(ResourceConverterContext context, boolean isChild) {
        ValueMap valueMap = (ValueMap)this.resource.adaptTo(ValueMap.class);
        Map<String, Object> props = this.getProperties((Map<String, Object>)valueMap, context, isChild);
        props.put("name", this.resource.getName());
        return props;
    }

    private Map<String, Object> getProperties(Map<String, Object> properties, ResourceConverterContext context, boolean isChild) {
        HashMap<String, Object> props = new HashMap<String, Object>();
        if (properties != null) {
            for (String key : properties.keySet()) {
                boolean isAllowed = this.isAllowedPrefix(key, context, PREFIX_ALLOWED);
                if (isChild && !context.isShowAllProperties()) {
                    isAllowed = this.isAllowedPrefix(key, context, PREFIX_ALLOWED_SHORT);
                }
                if (!isAllowed) continue;
                Map<String, Object> value = properties.get(key);
                if (value instanceof Calendar) {
                    value = ISO8601.format((Calendar)((Calendar)((Object)value)));
                }
                if (value instanceof ValueMap) {
                    value = this.getProperties((Map<String, Object>)((ValueMap)value), context, isChild);
                }
                props.put(key, value);
            }
        }
        return props;
    }

    protected List<Entity> getEntities(ResourceConverterContext context, Iterator<Resource> children) throws BuilderException {
        return new LinkedList<Entity>();
    }

    protected List<Entity> getEntities(ResourceConverterContext context) throws BuilderException {
        return this.getEntities(context, this.listChildren().iterator());
    }

    protected Entity getEntity(String[] clazz, String title, List<Action> actions, List<Entity> entities, List<Link> links, Map<String, Object> properties) throws BuilderException {
        Entity entity = (Entity)new EntityBuilder().setClass(clazz).setTitle(title).setActions(actions).setEntities(entities).setLinks(links).setProperties(properties).build();
        return entity;
    }

    protected List<Link> getLinks(ResourceConverterContext context) throws BuilderException, ResourceConverterException {
        HashMap<String, String[]> pagingParameters = new HashMap<String, String[]>();
        pagingParameters.putAll(context.getParameters());
        LinkedList<Link> links = new LinkedList<Link>();
        links.add(this.getLink("self", this.buildURL(context, this.resource.getPath(), ".json", pagingParameters), null));
        return links;
    }

    protected Link getLink(String[] rel, String href, String type) throws BuilderException {
        Link link = (Link)new LinkBuilder().setRel(rel).setHref(href).setType(type).build();
        return link;
    }

    protected Link getLink(String rel, String href, String type) throws BuilderException {
        return this.getLink(new String[]{rel}, href, type);
    }

    protected List<Action> getActions(ResourceConverterContext context) throws BuilderException, ResourceConverterException {
        return new LinkedList<Action>();
    }

    @Override
    public Entity toEntity(ResourceConverterContext context) throws ResourceConverterException {
        try {
            ResourceConverterContext ctx = context;
            Entity entity = (Entity)new EntityBuilder().setClass(this.getClazz()).setProperties(this.getProperties(ctx)).setEntities(this.getEntities(ctx)).setLinks(this.getLinks(ctx)).setActions(this.getActions(ctx)).build();
            return entity;
        }
        catch (BuilderException e) {
            throw new ResourceConverterException((Throwable)e);
        }
    }

    @Override
    public Entity toSubEntity(ResourceConverterContext context) throws ResourceConverterException {
        try {
            LinkedList<Link> links = new LinkedList<Link>();
            links.add(this.getLink("self", this.buildURL(context, this.resource.getPath(), ".json"), null));
            Entity entity = (Entity)new EntityBuilder().setClass(this.getClazz()).setRel(new String[]{"child"}).setProperties(this.getProperties(context, true)).setLinks(links).build();
            return entity;
        }
        catch (BuilderException e) {
            throw new ResourceConverterException((Throwable)e);
        }
    }

    protected String buildURL(ResourceConverterContext context, String resourcePath, String extension) throws ResourceConverterException {
        return this.buildURL(context, resourcePath, extension, null);
    }

    protected String getNextPageURL(ResourceConverterContext context) throws ResourceConverterException {
        int offset = context.getOffset();
        int limit = context.getLimit();
        Filter<Resource> filter = context.getFilter();
        if (offset + limit >= Resources.getSize(this.listChildren().iterator(), filter)) {
            return null;
        }
        return this.buildPagingURL(context, offset += limit);
    }

    protected String getPrevPageURL(ResourceConverterContext context) throws ResourceConverterException {
        int offset = context.getOffset();
        if (offset == 0) {
            return null;
        }
        int limit = context.getLimit();
        if ((offset -= limit) < 0) {
            offset = 0;
        }
        return this.buildPagingURL(context, offset);
    }

    private String buildPagingURL(ResourceConverterContext context, int offset) throws ResourceConverterException {
        HashMap<String, String[]> pagingParameters = new HashMap<String, String[]>();
        pagingParameters.putAll(context.getParameters());
        pagingParameters.put("offset", new String[]{Integer.toString(offset)});
        pagingParameters.put("limit", new String[]{Integer.toString(context.getLimit())});
        return this.buildURL(context, this.resource.getPath(), ".json", pagingParameters);
    }

    private String buildURL(ResourceConverterContext context, String resourcePath, String extension, Map<String, String[]> additionalParameters) throws ResourceConverterException {
        StringBuilder url = new StringBuilder();
        if (context.isAbsolutURI()) {
            url.append(context.getScheme());
            url.append("://");
            url.append(context.getServerName());
            if ("http".equals(context.getScheme()) && context.getServerPort() != 80 || "https".equals(context.getScheme()) && context.getServerPort() != 443) {
                url.append(":");
                url.append(context.getServerPort());
            }
        } else {
            resourcePath = URIUtils.relativize(context.getRequestPathInfo(), resourcePath);
        }
        url.append(URIUtils.urlEncodePath(resourcePath));
        if (extension != null) {
            url.append(extension);
        }
        try {
            HashMap<String, String[]> parameters = new HashMap<String, String[]>();
            if (additionalParameters != null) {
                parameters.putAll(additionalParameters);
            }
            boolean first = true;
            for (String param : parameters.keySet()) {
                for (String value : (String[])parameters.get(param)) {
                    if (!first) {
                        url.append('&');
                    } else {
                        url.append('?');
                        first = false;
                    }
                    url.append(URLEncoder.encode(param, "UTF-8"));
                    url.append('=');
                    url.append(URLEncoder.encode(value, "UTF-8"));
                }
            }
        }
        catch (UnsupportedEncodingException ignored) {
            this.log.error("URL encoding failed", (Throwable)ignored);
        }
        return url.toString();
    }
}