001/* 002 * (C) Copyright 2016 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 * Florent Guillaume 018 * Kevin Leturc 019 */ 020package org.nuxeo.ecm.core.storage.dbs; 021 022import static org.nuxeo.ecm.core.storage.dbs.DBSDocument.KEY_PREFIX; 023 024import java.io.Serializable; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029import java.util.Map.Entry; 030 031import org.nuxeo.ecm.core.storage.State; 032 033/** 034 * Function to flatten and convert {@link State} into NXQL {@link Map}<{@link String}, {@link Serializable}>. 035 * 036 * @since 8.3 037 */ 038public class DBSStateFlattener { 039 040 protected final Map<String, String> keyMappings; 041 042 public DBSStateFlattener() { 043 this.keyMappings = Collections.emptyMap(); 044 } 045 046 public DBSStateFlattener(Map<String, String> keyMappings) { 047 this.keyMappings = keyMappings != null ? keyMappings : Collections.emptyMap(); 048 } 049 050 /** 051 * Flattens with optional property key mappings. 052 * @param state state 053 * @return flattened result 054 * @since 9.3 055 */ 056 public Map<String, Serializable> flatten(State state) { 057 Map<String, Serializable> map = new HashMap<>(); 058 flatten(map, state, null); 059 return map; 060 } 061 062 protected void flatten(Map<String, Serializable> map, State state, String prefix) { 063 for (Entry<String, Serializable> en : state.entrySet()) { 064 String key = en.getKey(); 065 Serializable value = en.getValue(); 066 String name; 067 String realName = keyMappings.get(key); 068 if (realName != null) { 069 name = realName; 070 } else if (key.startsWith(KEY_PREFIX)) { 071 name = DBSSession.convToNXQL(key); 072 if (name == null) { 073 // present in state but not returned to caller 074 continue; 075 } 076 } else { 077 name = key; 078 } 079 name = prefix == null ? name : prefix + name; 080 if (value instanceof State) { 081 flatten(map, (State) value, name + '/'); 082 } else if (value instanceof List) { 083 String nameSlash = name + '/'; 084 int i = 0; 085 for (Object v : (List<?>) value) { 086 if (v instanceof State) { 087 flatten(map, (State) v, nameSlash + i + '/'); 088 } else { 089 map.put(nameSlash + i, (Serializable) v); 090 } 091 i++; 092 } 093 } else if (value instanceof Object[]) { 094 String nameSlash = name + '/'; 095 int i = 0; 096 for (Object v : (Object[]) value) { 097 map.put(nameSlash + i, (Serializable) v); 098 i++; 099 } 100 } else { 101 map.put(name, value); 102 } 103 } 104 } 105 106}