Java tutorial
/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.wysiwyg.server.internal.plugin.macro; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import org.apache.commons.lang3.StringUtils; import org.xwiki.component.annotation.Component; import org.xwiki.gwt.wysiwyg.client.plugin.macro.MacroDescriptor; import org.xwiki.gwt.wysiwyg.client.plugin.macro.MacroService; import org.xwiki.gwt.wysiwyg.client.plugin.macro.ParameterDescriptor; import org.xwiki.gwt.wysiwyg.client.plugin.macro.ParameterType; import org.xwiki.rendering.macro.Macro; import org.xwiki.rendering.macro.MacroCategoryManager; import org.xwiki.rendering.macro.MacroId; import org.xwiki.rendering.macro.MacroManager; import org.xwiki.rendering.syntax.Syntax; import org.xwiki.rendering.syntax.SyntaxFactory; import org.xwiki.wysiwyg.server.plugin.macro.MacroDescriptorTranslator; /** * XWiki specific implementation of {@link MacroService}. * * @version $Id: 4bc82075ad51035c0f2c7d640b9ff2b37141b238 $ */ @Component @Singleton public class XWikiMacroService implements MacroService { /** * The syntax factory used to create {@link Syntax} instances from string syntax identifiers. */ @Inject private SyntaxFactory syntaxFactory; /** * The macro manager used to retrieve macros. */ @Inject private MacroManager macroManager; /** * The macro category manager used to retrieve macro categories. */ @Inject private MacroCategoryManager categoryManager; /** * The component used to translate macro descriptors into the execution context language. */ @Inject private MacroDescriptorTranslator macroDescriptorTranslator; @Override public MacroDescriptor getMacroDescriptor(String macroId, String syntaxId) { return macroDescriptorTranslator.translate(getUntranslatedMacroDescriptor(macroId, syntaxId)); } /** * @param macroId the macro identifier * @param syntaxId the syntax identifier * @return the untranslated macro descriptor for the specified macro */ private MacroDescriptor getUntranslatedMacroDescriptor(String macroId, String syntaxId) { try { MacroId macroIdObject = new MacroId(macroId, syntaxFactory.createSyntaxFromIdString(syntaxId)); Macro<?> macro = macroManager.getMacro(macroIdObject); org.xwiki.rendering.macro.descriptor.MacroDescriptor descriptor = macro.getDescriptor(); ParameterDescriptor contentDescriptor = null; if (descriptor.getContentDescriptor() != null) { contentDescriptor = new ParameterDescriptor(); contentDescriptor.setId("content"); contentDescriptor.setName("Content"); contentDescriptor.setDescription(descriptor.getContentDescriptor().getDescription()); // Just a hack to distinguish between regular strings and large strings. contentDescriptor.setType(createMacroParameterType(StringBuffer.class)); contentDescriptor.setMandatory(descriptor.getContentDescriptor().isMandatory()); } // We use a linked hash map to preserve the order of the macro parameters. Map<String, ParameterDescriptor> parameterDescriptorMap = new LinkedHashMap<String, ParameterDescriptor>(); for (Map.Entry<String, org.xwiki.rendering.macro.descriptor.ParameterDescriptor> entry : descriptor .getParameterDescriptorMap().entrySet()) { parameterDescriptorMap.put(entry.getKey(), createMacroParameterDescriptor(entry.getValue())); } MacroDescriptor result = new MacroDescriptor(); result.setId(macroIdObject.getId()); result.setName(descriptor.getName()); result.setDescription(descriptor.getDescription()); result.setSupportingInlineMode(macro.supportsInlineMode()); // NOTE: we should set the category also, but we need a new method in MacroCategoryManager. result.setContentDescriptor(contentDescriptor); result.setParameterDescriptorMap(parameterDescriptorMap); return result; } catch (Exception e) { throw new RuntimeException("Exception while retrieving macro descriptor.", e); } } /** * Creates a {@link ParameterDescriptor} from a {@link org.xwiki.rendering.macro.descriptor.ParameterDescriptor}. * * @param descriptor a macro parameter descriptor from the rendering package * @return a macro parameter descriptor from the WYSIWYG package */ private ParameterDescriptor createMacroParameterDescriptor( org.xwiki.rendering.macro.descriptor.ParameterDescriptor descriptor) { ParameterDescriptor result = new ParameterDescriptor(); result.setId(descriptor.getId()); // Fall-back on parameter id if parameter name if not specified. // See XWIKI-4558 (Add macro parameter display name support to wiki macros). result.setName(StringUtils.isBlank(descriptor.getName()) ? descriptor.getId() : descriptor.getName()); result.setDescription(descriptor.getDescription()); result.setType(createMacroParameterType(descriptor.getParameterType())); Object defaultValue = descriptor.getDefaultValue(); if (defaultValue != null) { result.setDefaultValue(String.valueOf(defaultValue)); } result.setMandatory(descriptor.isMandatory()); return result; } /** * NOTE: We can't send a {@link Type} instance to the client side because GWT can't serialize it so we have to * convert it to a {@link ParameterType} instance. * * @param type the type that defines the values a macro parameter can have * @return the parameter type associated with the given type */ private ParameterType createMacroParameterType(Type type) { ParameterType parameterType = new ParameterType(); if (type instanceof Class) { Class<?> parameterClass = (Class<?>) type; parameterType.setName(parameterClass.getName()); if (parameterClass.isEnum()) { Object[] parameterClassConstants = parameterClass.getEnumConstants(); Map<String, String> parameterTypeConstants = new LinkedHashMap<String, String>(); for (int i = 0; i < parameterClassConstants.length; i++) { String constant = String.valueOf(parameterClassConstants[i]); // We leave the constant unlocalized for now. parameterTypeConstants.put(constant, constant); } parameterType.setEnumConstants(parameterTypeConstants); } } return parameterType; } @Override public List<MacroDescriptor> getMacroDescriptors(String syntaxId) { try { Syntax syntax = syntaxFactory.createSyntaxFromIdString(syntaxId); List<MacroDescriptor> descriptors = new ArrayList<MacroDescriptor>(); for (String category : categoryManager.getMacroCategories(syntax)) { for (MacroId macroId : categoryManager.getMacroIds(category, syntax)) { MacroDescriptor descriptor = getUntranslatedMacroDescriptor(macroId.getId(), syntaxId); descriptor.setCategory(category); descriptors.add(macroDescriptorTranslator.translate(descriptor)); } } Collections.sort(descriptors, new Comparator<MacroDescriptor>() { public int compare(MacroDescriptor alice, MacroDescriptor bob) { return alice.getName().compareTo(bob.getName()); } }); return descriptors; } catch (Exception e) { throw new RuntimeException( "Exception while retrieving the list of macro descriptors for syntax [" + syntaxId + "].", e); } } }