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 ) {} // This is fine 116 } 117 118 if( editor != null ) { 119 final String[] editorlist = getEditorList(); 120 editor = editor.trim(); 121 for( final String s : editorlist ) { 122 if( s.equalsIgnoreCase( editor ) ) { 123 return s; 124 } 125 } 126 } 127 128 return EDITOR_PLAIN; 129 } 130 131 /** {@inheritDoc} */ 132 @Override 133 public String[] getEditorList() { 134 final String[] editors = new String[ m_editors.size() ]; 135 final Set< String > keys = m_editors.keySet(); 136 137 return keys.toArray( editors ); 138 } 139 140 /** {@inheritDoc} */ 141 @Override 142 public String getEditorPath( final Context context ) { 143 final String editor = getEditorName( context ); 144 final WikiEditorInfo ed = m_editors.get( editor ); 145 final String path; 146 if( ed != null ) { 147 path = ed.getPath(); 148 } else { 149 path = "editors/"+editor+".jsp"; 150 } 151 152 return path; 153 } 154 155 /** Contains info about an editor. */ 156 private static final class WikiEditorInfo extends WikiModuleInfo { 157 private String m_path; 158 159 static WikiEditorInfo newInstance( final String name, final Element el ) { 160 if( name == null || name.isEmpty() ) { 161 return null; 162 } 163 final WikiEditorInfo info = new WikiEditorInfo( name ); 164 info.initializeFromXML( el ); 165 return info; 166 } 167 168 /** {@inheritDoc} */ 169 @Override 170 protected void initializeFromXML( final Element el ) { 171 super.initializeFromXML( el ); 172 m_path = el.getChildText("path"); 173 } 174 175 private WikiEditorInfo( final String name ) { 176 super( name ); 177 } 178 179 public String getPath() { 180 return m_path; 181 } 182 } 183 184 /** {@inheritDoc} */ 185 @Override 186 public Collection< WikiModuleInfo > modules() { 187 return modules( m_editors.values().iterator() ); 188 } 189 190 /** {@inheritDoc} */ 191 @Override 192 public WikiEditorInfo getModuleInfo( final String moduleName ) { 193 return m_editors.get( moduleName ); 194 } 195 196}