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