001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.ui; 020 021import org.apache.logging.log4j.LogManager; 022import org.apache.logging.log4j.Logger; 023import org.apache.wiki.api.core.Context; 024import org.apache.wiki.api.core.ContextEnum; 025import org.apache.wiki.api.core.Engine; 026import org.apache.wiki.api.exceptions.NoSuchVariableException; 027import org.apache.wiki.modules.BaseModuleManager; 028import org.apache.wiki.modules.WikiModuleInfo; 029import org.apache.wiki.preferences.Preferences; 030import org.apache.wiki.util.XmlUtil; 031import org.apache.wiki.variables.VariableManager; 032import org.jdom2.Element; 033 034import java.util.Collection; 035import java.util.HashMap; 036import java.util.List; 037import java.util.Map; 038import java.util.Properties; 039import java.util.Set; 040 041 042/** 043 * Defines an editor manager. An editor can be added by adding a suitable JSP file under templates/default/editors 044 * If you want your editor to include any scripts or something, you can simply request it by adding the following in your 045 * {@code ini/jspwiki_module.xml}: 046 * 047 * <pre> 048 * <modules> 049 * <editor name="myeditor"> 050 * <author>Janne Jalkanen</author> 051 * <script>foo.js</script> 052 * <stylesheet>foo.css</stylesheet> 053 * <path>editors/myeditor.jsp</path> 054 * </editor> 055 * </modules> 056 * </pre> 057 * 058 * @since 2.4 059 */ 060public class DefaultEditorManager extends BaseModuleManager implements EditorManager { 061 062 private Map< String, WikiEditorInfo > m_editors; 063 064 private static final Logger LOG = LogManager.getLogger( DefaultEditorManager.class ); 065 066 public DefaultEditorManager( final Engine engine ) { 067 super( engine ); 068 } 069 070 /** 071 * {@inheritDoc} 072 * 073 * Initializes the EditorManager. It also registers any editors it can find. 074 */ 075 @Override 076 public void initialize( final Engine engine, final Properties props ) { 077 registerEditors(); 078 } 079 080 /** This method goes through the jspwiki_module.xml files and hunts for editors. Any editors found are put in the registry. */ 081 private void registerEditors() { 082 LOG.info( "Registering editor modules" ); 083 m_editors = new HashMap<>(); 084 085 // Register all editors which have created a resource containing its properties. Get all resources of all modules 086 final List< Element > editors = XmlUtil.parse( PLUGIN_RESOURCE_LOCATION, "/modules/editor" ); 087 for( final Element pluginEl : editors ) { 088 final String name = pluginEl.getAttributeValue( "name" ); 089 final WikiEditorInfo info = WikiEditorInfo.newInstance( name, pluginEl ); 090 091 if( checkCompatibility( info ) ) { 092 m_editors.put( name, info ); 093 LOG.debug( "Registered editor " + name ); 094 } else { 095 LOG.info( "Editor '" + name + "' not compatible with this version of JSPWiki." ); 096 } 097 } 098 } 099 100 /** {@inheritDoc} */ 101 @Override 102 public String getEditorName( final Context context ) { 103 if( context.getRequestContext().equals( ContextEnum.PAGE_PREVIEW.getRequestContext() ) ) { 104 return EDITOR_PREVIEW; 105 } 106 107 // User has set an editor in preferences 108 String editor = Preferences.getPreference( context, PARA_EDITOR ); 109 110 /* FIXME: actual default 'editor' property is read by the Preferences class */ 111 if( editor == null ) { 112 // or use the default editor in jspwiki.properties 113 try { 114 editor = m_engine.getManager( VariableManager.class ).getValue( context, PROP_EDITORTYPE ); 115 } catch( final NoSuchVariableException e ) { 116 LOG.debug(e.getMessage(), e); 117 } // This is fine 118 } 119 120 if( editor != null ) { 121 final String[] editorlist = getEditorList(); 122 editor = editor.trim(); 123 for( final String s : editorlist ) { 124 if( s.equalsIgnoreCase( editor ) ) { 125 return s; 126 } 127 } 128 } 129 130 return EDITOR_PLAIN; 131 } 132 133 /** {@inheritDoc} */ 134 @Override 135 public String[] getEditorList() { 136 final String[] editors = new String[ m_editors.size() ]; 137 final Set< String > keys = m_editors.keySet(); 138 139 return keys.toArray( editors ); 140 } 141 142 /** {@inheritDoc} */ 143 @Override 144 public String getEditorPath( final Context context ) { 145 final String editor = getEditorName( context ); 146 final WikiEditorInfo ed = m_editors.get( editor ); 147 final String path; 148 if( ed != null ) { 149 path = ed.getPath(); 150 } else { 151 path = "editors/"+editor+".jsp"; 152 } 153 154 return path; 155 } 156 157 /** Contains info about an editor. */ 158 private static final class WikiEditorInfo extends WikiModuleInfo { 159 private String m_path; 160 161 static WikiEditorInfo newInstance( final String name, final Element el ) { 162 if( name == null || name.isEmpty() ) { 163 return null; 164 } 165 final WikiEditorInfo info = new WikiEditorInfo( name ); 166 info.initializeFromXML( el ); 167 return info; 168 } 169 170 /** {@inheritDoc} */ 171 @Override 172 protected void initializeFromXML( final Element el ) { 173 super.initializeFromXML( el ); 174 m_path = el.getChildText("path"); 175 } 176 177 private WikiEditorInfo( final String name ) { 178 super( name ); 179 } 180 181 public String getPath() { 182 return m_path; 183 } 184 } 185 186 /** {@inheritDoc} */ 187 @Override 188 public Collection< WikiModuleInfo > modules() { 189 return modules( m_editors.values().iterator() ); 190 } 191 192 /** {@inheritDoc} */ 193 @Override 194 public WikiEditorInfo getModuleInfo( final String moduleName ) { 195 return m_editors.get( moduleName ); 196 } 197 198}