001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Thierry Delprat
018 */
019package org.nuxeo.ecm.platform.forms.layout.export;
020
021import java.io.IOException;
022import java.util.Collections;
023import java.util.List;
024
025import javax.ws.rs.GET;
026import javax.ws.rs.Path;
027import javax.ws.rs.PathParam;
028import javax.ws.rs.QueryParam;
029import javax.ws.rs.core.Context;
030import javax.ws.rs.core.UriInfo;
031
032import org.apache.commons.lang3.StringUtils;
033import org.nuxeo.ecm.core.io.registry.MarshallerHelper;
034import org.nuxeo.ecm.core.io.registry.context.RenderingContext;
035import org.nuxeo.ecm.core.io.registry.context.RenderingContext.CtxBuilder;
036import org.nuxeo.ecm.platform.forms.layout.api.BuiltinModes;
037import org.nuxeo.ecm.platform.forms.layout.api.LayoutDefinition;
038import org.nuxeo.ecm.platform.forms.layout.api.converters.LayoutConversionContext;
039import org.nuxeo.ecm.platform.forms.layout.api.converters.LayoutDefinitionConverter;
040import org.nuxeo.ecm.platform.forms.layout.api.converters.WidgetDefinitionConverter;
041import org.nuxeo.ecm.platform.forms.layout.api.service.LayoutStore;
042import org.nuxeo.ecm.platform.types.TypeManager;
043import org.nuxeo.ecm.webengine.model.view.TemplateView;
044import org.nuxeo.runtime.api.Framework;
045
046/**
047 * Exports and presents documentation about layouts definitions
048 *
049 * @author Tiry
050 * @since 5.5
051 */
052public class LayoutResource {
053
054    public static final String DEFAULT_DOCUMENT_LAYOUT_MODE = BuiltinModes.EDIT;
055
056    public static final String DEFAULT_CONVERSION_CATEGORY = "standalone";
057
058    public static final String DEFAULT_LANGUAGE = "en";
059
060    protected final String category;
061
062    protected LayoutStore service;
063
064    protected List<String> registeredLayoutNames;
065
066    public LayoutResource(String category) {
067        this.category = category;
068        service = Framework.getService(LayoutStore.class);
069        registeredLayoutNames = service.getLayoutDefinitionNames(category);
070        // sort so that order is deterministic
071        Collections.sort(registeredLayoutNames);
072    }
073
074    protected TemplateView getTemplate(String name, UriInfo uriInfo) {
075        String baseURL = uriInfo.getAbsolutePath().toString();
076        if (!baseURL.endsWith("/")) {
077            baseURL += "/";
078        }
079        return new TemplateView(this, name).arg("baseURL", baseURL).arg("layoutNames", registeredLayoutNames);
080    }
081
082    @GET
083    public Object doGet(@QueryParam("layoutName") String layoutName, @Context UriInfo uriInfo) {
084        TemplateView tpl = getTemplate("layouts.ftl", uriInfo);
085        if (layoutName != null) {
086            LayoutDefinition layoutDef = service.getLayoutDefinition(category, layoutName);
087            tpl.arg("layoutDefinition", layoutDef);
088        }
089        return tpl;
090    }
091
092    @GET
093    @Path("json")
094    public String getAsJson(@QueryParam("layoutName") String layoutName, @QueryParam("lang") String lang,
095            @QueryParam("convertCat") String conversionCategory) throws IOException {
096        if (layoutName != null) {
097            if (StringUtils.isBlank(lang)) {
098                lang = DEFAULT_LANGUAGE;
099            }
100            if (StringUtils.isBlank(conversionCategory)) {
101                conversionCategory = DEFAULT_CONVERSION_CATEGORY;
102            }
103            LayoutDefinition layoutDef = service.getLayoutDefinition(category, layoutName);
104            if (layoutDef != null) {
105                LayoutConversionContext ctx = new LayoutConversionContext(lang, null);
106                List<LayoutDefinitionConverter> layoutConverters = service.getLayoutConverters(conversionCategory);
107                // pass layout converters now
108                for (LayoutDefinitionConverter conv : layoutConverters) {
109                    layoutDef = conv.getLayoutDefinition(layoutDef, ctx);
110                }
111                if (layoutDef != null) {
112                    List<WidgetDefinitionConverter> widgetConverters = service.getWidgetConverters(conversionCategory);
113                    RenderingContext renderingCtx = CtxBuilder.param(LayoutExportConstants.CATEGORY_PARAMETER, category)
114                                                              .param(LayoutExportConstants.LAYOUT_CONTEXT_PARAMETER,
115                                                                      ctx)
116                                                              .paramList(
117                                                                      LayoutExportConstants.WIDGET_CONVERTERS_PARAMETER,
118                                                                      widgetConverters)
119                                                              .get();
120                    return MarshallerHelper.objectToJson(layoutDef, renderingCtx);
121                }
122            }
123        }
124        return "No layout found";
125    }
126
127    @GET
128    @Path("docType/{docType}")
129    public String getLayoutsForTypeAsJson(@PathParam("docType") String docType, @QueryParam("mode") String mode,
130            @QueryParam("lang") String lang, @QueryParam("convertCat") String conversionCategory) throws IOException {
131
132        if (StringUtils.isBlank(mode)) {
133            mode = DEFAULT_DOCUMENT_LAYOUT_MODE;
134        }
135        if (StringUtils.isBlank(lang)) {
136            lang = DEFAULT_LANGUAGE;
137        }
138        if (StringUtils.isBlank(conversionCategory)) {
139            conversionCategory = DEFAULT_CONVERSION_CATEGORY;
140        }
141        TypeManager tm = Framework.getService(TypeManager.class);
142        String[] layoutNames = tm.getType(docType).getLayouts(mode);
143
144        LayoutConversionContext ctx = new LayoutConversionContext(lang, null);
145        List<LayoutDefinitionConverter> layoutConverters = service.getLayoutConverters(conversionCategory);
146        List<WidgetDefinitionConverter> widgetConverters = service.getWidgetConverters(conversionCategory);
147
148        LayoutDefinitions layoutDefinitions = new LayoutDefinitions();
149        for (String layoutName : layoutNames) {
150            LayoutDefinition layoutDef = service.getLayoutDefinition(category, layoutName);
151
152            // pass layout converters now
153            for (LayoutDefinitionConverter conv : layoutConverters) {
154                layoutDef = conv.getLayoutDefinition(layoutDef, ctx);
155            }
156            if (layoutDef != null) {
157                layoutDefinitions.add(layoutDef);
158            }
159        }
160        RenderingContext renderingCtx = CtxBuilder.param(LayoutExportConstants.CATEGORY_PARAMETER, category)
161                                                  .param(LayoutExportConstants.LAYOUT_CONTEXT_PARAMETER, ctx)
162                                                  .paramList(LayoutExportConstants.WIDGET_CONVERTERS_PARAMETER,
163                                                          widgetConverters)
164                                                  .get();
165        return MarshallerHelper.objectToJson(layoutDefinitions, renderingCtx);
166    }
167}