001/* 002 * (C) Copyright 2015 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 * Nicolas Chapurlat <nchapurlat@nuxeo.com> 018 */ 019 020package org.nuxeo.ecm.platform.usermanager.io; 021 022import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; 023import static org.nuxeo.ecm.core.io.registry.reflect.Instantiations.SINGLETON; 024import static org.nuxeo.ecm.core.io.registry.reflect.Priorities.REFERENCE; 025 026import java.io.IOException; 027import java.io.OutputStream; 028import java.util.Arrays; 029import java.util.Collection; 030import java.util.List; 031 032import javax.inject.Inject; 033 034import org.codehaus.jackson.JsonGenerator; 035import org.nuxeo.ecm.core.api.DocumentModel; 036import org.nuxeo.ecm.core.api.NuxeoGroup; 037import org.nuxeo.ecm.core.api.model.Property; 038import org.nuxeo.ecm.core.io.marshallers.json.ExtensibleEntityJsonWriter; 039import org.nuxeo.ecm.core.io.marshallers.json.OutputStreamWithJsonWriter; 040import org.nuxeo.ecm.core.io.marshallers.json.enrichers.AbstractJsonEnricher; 041import org.nuxeo.ecm.core.io.registry.Writer; 042import org.nuxeo.ecm.core.io.registry.reflect.Setup; 043import org.nuxeo.ecm.platform.usermanager.UserManager; 044 045import com.thoughtworks.xstream.io.json.JsonWriter; 046 047/** 048 * Convert {@link NuxeoGroup} to Json. 049 * <p> 050 * This marshaller is enrichable: register class implementing {@link AbstractJsonEnricher} and managing 051 * {@link NuxeoGroup}. 052 * </p> 053 * <p> 054 * This marshaller is also extensible: extend it and simply override 055 * {@link ExtensibleEntityJsonWriter#extend(NuxeoGroup, JsonWriter)}. 056 * </p> 057 * <p> 058 * Format is: 059 * 060 * <pre> 061 * {@code 062 * { 063 * "entity-type":"group", 064 * "groupname": "GROUP_NAME", <- deprecated, for backward compatibility 065 * "grouplabel": "GROUP_DISPLAY_NAME", <- deprecated, for backward compatibility 066 * "id": "GROUP_NAME", 067 * "properties":{ <- depending on the group schema / format is managed by {@link DocumentPropertyJsonWriter} 068 * "groupname":"GROUP_NAME", 069 * "grouplabel":"GROUP_DISPLAY_NAME", 070 * "description": "GROUP_DESCRIPTION" 071 * }, 072 * "memberUsers": [ 073 * "USERNAME1", 074 * "USERNAME2", 075 * ... 076 * ], 077 * "memberGroups": [ 078 * "GROUPNAME1", 079 * "GROUPNAME2", 080 * ... 081 * ], 082 * "parentGroups": [ 083 * "GROUPNAME1", 084 * "GROUPNAME2", 085 * ... 086 * ] 087 * <-- contextParameters if there are enrichers activated 088 * <-- additional property provided by extend() method 089 * } 090 * </pre> 091 * </p> 092 * @since 7.2 093 */ 094@Setup(mode = SINGLETON, priority = REFERENCE) 095public class NuxeoGroupJsonWriter extends ExtensibleEntityJsonWriter<NuxeoGroup> { 096 097 public static final String ENTITY_TYPE = "group"; 098 099 /** 100 * @since 9.3 101 */ 102 public static final String MEMBER_USERS_FETCH_PROPERTY = "memberUsers"; 103 104 /** 105 * @since 9.3 106 */ 107 public static final String MEMBER_GROUPS_FETCH_PROPERTY = "memberGroups"; 108 109 /** 110 * @since 9.3 111 */ 112 public static final String PARENT_GROUPS_FETCH_PROPERTY = "parentGroups"; 113 114 /** 115 * @since 9.3 116 */ 117 public static final String GROUP_NAME_COMPATIBILITY_FIELD = "groupname"; 118 119 /** 120 * @since 9.3 121 */ 122 public static final String GROUP_LABEL_COMPATIBILITY_FIELD = "grouplabel"; 123 124 @Inject 125 private UserManager userManager; 126 127 public NuxeoGroupJsonWriter() { 128 super(ENTITY_TYPE, NuxeoGroup.class); 129 } 130 131 @Override 132 protected void writeEntityBody(NuxeoGroup group, JsonGenerator jg) throws IOException { 133 // for backward compatibility, those are now in the 'properties' field 134 jg.writeStringField(GROUP_NAME_COMPATIBILITY_FIELD, group.getName()); 135 jg.writeStringField(GROUP_LABEL_COMPATIBILITY_FIELD, group.getLabel()); 136 137 jg.writeStringField("id", group.getName()); 138 writeProperties(group, jg); 139 writeMemberUsers(group, jg); 140 writeMemberGroups(group, jg); 141 writeParentGroups(group, jg); 142 } 143 144 protected void writeProperties(NuxeoGroup group, JsonGenerator jg) throws IOException { 145 DocumentModel doc = group.getModel(); 146 if (doc == null) { 147 return; 148 } 149 String groupSchema = userManager.getGroupSchemaName(); 150 Collection<Property> properties = doc.getPropertyObjects(groupSchema); 151 if (properties.isEmpty()) { 152 return; 153 } 154 155 List<String> excludedProperties = Arrays.asList(userManager.getGroupMembersField(), 156 userManager.getGroupSubGroupsField(), userManager.getGroupParentGroupsField()); 157 Writer<Property> propertyWriter = registry.getWriter(ctx, Property.class, APPLICATION_JSON_TYPE); 158 jg.writeObjectFieldStart("properties"); 159 for (Property property : properties) { 160 String localName = property.getField().getName().getLocalName(); 161 if (!excludedProperties.contains(localName)) { 162 jg.writeFieldName(localName); 163 OutputStream out = new OutputStreamWithJsonWriter(jg); 164 propertyWriter.write(property, Property.class, Property.class, APPLICATION_JSON_TYPE, out); 165 } 166 } 167 jg.writeEndObject(); 168 } 169 170 protected void writeMemberUsers(NuxeoGroup group, JsonGenerator jg) throws IOException { 171 if (ctx.getFetched(ENTITY_TYPE).contains(MEMBER_USERS_FETCH_PROPERTY)) { 172 jg.writeArrayFieldStart(MEMBER_USERS_FETCH_PROPERTY); 173 for (String user : group.getMemberUsers()) { 174 jg.writeString(user); 175 } 176 jg.writeEndArray(); 177 } 178 } 179 180 protected void writeMemberGroups(NuxeoGroup group, JsonGenerator jg) throws IOException { 181 if (ctx.getFetched(ENTITY_TYPE).contains(MEMBER_GROUPS_FETCH_PROPERTY)) { 182 jg.writeArrayFieldStart(MEMBER_GROUPS_FETCH_PROPERTY); 183 for (String user : group.getMemberGroups()) { 184 jg.writeString(user); 185 } 186 jg.writeEndArray(); 187 } 188 } 189 190 protected void writeParentGroups(NuxeoGroup group, JsonGenerator jg) throws IOException { 191 if (ctx.getFetched(ENTITY_TYPE).contains(PARENT_GROUPS_FETCH_PROPERTY)) { 192 jg.writeArrayFieldStart(PARENT_GROUPS_FETCH_PROPERTY); 193 for (String user : group.getParentGroups()) { 194 jg.writeString(user); 195 } 196 jg.writeEndArray(); 197 } 198 } 199 200}