001/* 002 * (C) Copyright 2006-2007 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 * Jean-Marc Orliaguet, Chalmers 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.theme.presets; 023 024import java.util.ArrayList; 025import java.util.List; 026import java.util.Map; 027import java.util.regex.Matcher; 028import java.util.regex.Pattern; 029 030import org.apache.commons.logging.Log; 031import org.apache.commons.logging.LogFactory; 032import org.nuxeo.theme.Manager; 033import org.nuxeo.theme.elements.ThemeElement; 034import org.nuxeo.theme.formats.styles.Style; 035import org.nuxeo.theme.themes.ThemeException; 036import org.nuxeo.theme.themes.ThemeManager; 037import org.nuxeo.theme.types.Type; 038import org.nuxeo.theme.types.TypeFamily; 039 040public class PresetManager { 041 042 static final Log log = LogFactory.getLog(PresetManager.class); 043 044 private static final Pattern manyPresetNamePattern = Pattern.compile(".*?\"(.*?)\".*?"); 045 046 private static final Pattern presetNamePattern = Pattern.compile("^\"(.*?)\"$"); 047 048 private static final Pattern globalPresetNamePattern = Pattern.compile("^\".*?\\((.*?)\\)\"$"); 049 050 private static final Pattern customPresetNamePattern = Pattern.compile("^\"(.*?)\"$"); 051 052 public static String extractPresetName(final String themeName, final String str) { 053 String s = str.trim(); 054 final Matcher globalPresetNameMatcher = globalPresetNamePattern.matcher(s); 055 if (globalPresetNameMatcher.find()) { 056 Matcher presetMatcher = presetNamePattern.matcher(s); 057 if (presetMatcher.find()) { 058 return presetMatcher.group(1); 059 } 060 } else if (themeName != null) { 061 final Matcher customPresetNameMatcher = customPresetNamePattern.matcher(s); 062 if (customPresetNameMatcher.find()) { 063 return String.format("%s/%s", themeName, customPresetNameMatcher.group(1)); 064 } 065 } 066 return null; 067 } 068 069 public static PresetType getPresetByName(final String name) { 070 return (PresetType) Manager.getTypeRegistry().lookup(TypeFamily.PRESET, name); 071 } 072 073 public static List<Type> getAllPresets() { 074 return Manager.getTypeRegistry().getTypes(TypeFamily.PRESET); 075 } 076 077 public static List<PresetType> getGlobalPresets(final String group, final String category) { 078 List<PresetType> presets = new ArrayList<PresetType>(); 079 for (Type type : getAllPresets()) { 080 PresetType preset = (PresetType) type; 081 if (category != null && !(category.equals(preset.getCategory()))) { 082 continue; 083 } 084 if (group != null && !preset.getGroup().equals(group)) { 085 continue; 086 } 087 if (preset instanceof CustomPresetType) { 088 continue; 089 } 090 presets.add(preset); 091 } 092 return presets; 093 } 094 095 public static PresetType getCustomPreset(final String themeName, final String presetName) { 096 return getPresetByName(String.format("%s/%s", themeName, presetName)); 097 } 098 099 public static List<PresetType> getCustomPresets(final String themeName) { 100 return getCustomPresets(themeName, null); 101 } 102 103 public static List<PresetType> getCustomPresets(final String themeName, final String category) { 104 List<PresetType> presets = new ArrayList<PresetType>(); 105 for (Type type : getAllPresets()) { 106 PresetType preset = (PresetType) type; 107 if (!(preset instanceof CustomPresetType)) { 108 continue; 109 } 110 if (category != null && !preset.getCategory().equals(category)) { 111 continue; 112 } 113 if (themeName != null && !preset.getGroup().equals(themeName)) { 114 continue; 115 } 116 presets.add(preset); 117 } 118 return presets; 119 } 120 121 public static String resolvePresets(final String themeName, String propertyValue) { 122 // first-pass 123 propertyValue = resolveVariables(themeName, propertyValue); 124 // second-pass 125 propertyValue = resolveVariables(themeName, propertyValue); 126 return propertyValue; 127 } 128 129 private static String resolveVariables(final String themeName, final String str) { 130 Matcher m = manyPresetNamePattern.matcher(str); 131 StringBuilder sb = new StringBuilder(); 132 int end = 0; 133 while (m.find()) { 134 end = m.end(1) + 1; 135 sb.append(str.substring(m.start(), m.start(1) - 1)); 136 String presetStr = String.format("\"%s\"", m.group(1)); 137 String presetName = extractPresetName(themeName, presetStr); 138 if (presetName == null) { 139 sb.append(presetStr); 140 continue; 141 } 142 PresetType preset = getPresetByName(presetName); 143 if (preset == null) { 144 log.warn(String.format("Preset '%s' could not be resolved in theme '%s'", presetName, themeName)); 145 sb.append(presetStr); 146 continue; 147 } 148 sb.append(preset.getValue()); 149 } 150 sb.append(str.substring(end)); 151 return sb.toString(); 152 } 153 154 public static void createCustomPreset(String themeName, String presetName, String category, String value, 155 String label, String description) { 156 CustomPresetType preset = new CustomPresetType(presetName, value, themeName, category, label, description); 157 Manager.getTypeRegistry().register(preset); 158 } 159 160 public static void editPreset(String themeName, String presetName, String value) { 161 PresetType preset = getCustomPreset(themeName, presetName); 162 preset.setValue(value); 163 } 164 165 public static void setPresetCategory(String themeName, String presetName, String category) { 166 PresetType preset = getCustomPreset(themeName, presetName); 167 preset.setCategory(category); 168 } 169 170 public static void renamePreset(String themeName, String oldName, String newName) throws ThemeException { 171 if (newName.equals("")) { 172 throw new ThemeException("Preset name cannot be empty"); 173 } 174 PresetType preset = getCustomPreset(themeName, oldName); 175 if (getCustomPreset(themeName, newName) != null) { 176 throw new ThemeException("Preset name already taken: " + newName); 177 } 178 Manager.getTypeRegistry().unregister(preset); 179 preset.setName(newName); 180 Manager.getTypeRegistry().register(preset); 181 } 182 183 public static void deletePreset(String themeName, String presetName) throws ThemeException { 184 PresetType preset = getCustomPreset(themeName, presetName); 185 if (getCustomPreset(themeName, presetName) == null) { 186 throw new ThemeException("Preset unknown: " + presetName); 187 } 188 Manager.getTypeRegistry().unregister(preset); 189 } 190 191 public static void clearCustomPresets(String themeName) { 192 for (PresetType preset : getCustomPresets(themeName)) { 193 Manager.getTypeRegistry().unregister(preset); 194 } 195 } 196 197 public static List<String> getUnidentifiedPresetNames(final String themeName) { 198 List<String> names = new ArrayList<String>(); 199 ThemeManager themeManager = Manager.getThemeManager(); 200 for (Style style : themeManager.getStyles()) { 201 202 if (style.isNamed()) { 203 if (!themeName.equals(themeManager.getThemeNameOfNamedObject(style))) { 204 continue; 205 } 206 } else { 207 ThemeElement theme = ThemeManager.getThemeOfFormat(style); 208 if (theme == null) { 209 continue; 210 } 211 if (!themeName.equals(theme.getName())) { 212 continue; 213 } 214 } 215 216 for (Map.Entry<Object, Object> entry : style.getAllProperties().entrySet()) { 217 String value = (String) entry.getValue(); 218 String s = value.trim(); 219 Matcher m = manyPresetNamePattern.matcher(value.trim()); 220 while (m.find()) { 221 String name = m.group(1); 222 String presetStr = String.format("\"%s\"", name); 223 String presetName = extractPresetName(themeName, presetStr); 224 if (presetName == null) { 225 continue; 226 } 227 // retain only local theme presets 228 if (globalPresetNamePattern.matcher(s).find()) { 229 continue; 230 } 231 PresetType preset = getPresetByName(presetName); 232 if (preset == null && !names.contains(name)) { 233 names.add(name); 234 } 235 } 236 } 237 } 238 return names; 239 } 240 241}