Update to moasdawiki-server 2.4.1

This commit is contained in:
Herbert Reiter
2020-12-27 16:31:10 +01:00
parent 09a2fb28f7
commit f5caf4bc50
5 changed files with 129 additions and 128 deletions
@@ -43,9 +43,7 @@ import androidx.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import android.widget.Toast;
import net.moasdawiki.plugin.Plugin; import net.moasdawiki.service.transform.TerminTransformer;
import net.moasdawiki.plugin.PluginService;
import net.moasdawiki.plugin.TerminPlugin;
import net.moasdawiki.util.PathUtils; import net.moasdawiki.util.PathUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -87,7 +85,7 @@ public class CalendarSyncAdapter extends AbstractThreadedSyncAdapter {
@Override @Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.d(TAG, "Begin of onPerformSync()"); Log.d(TAG, "Begin of onPerformSync()");
List<TerminPlugin.Event> events = getWikiEvents(); List<TerminTransformer.Event> events = getWikiEvents();
String calendarId = createCalendar(); String calendarId = createCalendar();
if (calendarId != null) { if (calendarId != null) {
deleteAllEvents(calendarId); deleteAllEvents(calendarId);
@@ -106,21 +104,15 @@ public class CalendarSyncAdapter extends AbstractThreadedSyncAdapter {
* Imports all events on Wiki pages to the Android calendar. * Imports all events on Wiki pages to the Android calendar.
*/ */
@NotNull @NotNull
private List<TerminPlugin.Event> getWikiEvents() { private List<TerminTransformer.Event> getWikiEvents() {
Log.d(TAG, "Reading Wiki events"); Log.d(TAG, "Reading Wiki events");
WikiEngineApplication app = (WikiEngineApplication) getContext(); WikiEngineApplication app = (WikiEngineApplication) getContext();
PluginService pluginService = app.getServiceLocator().getPluginService(); TerminTransformer terminTransformer = app.getTerminTransformer();
TerminPlugin terminPlugin = null; if (terminTransformer == null) {
for (Plugin plugin : pluginService.getPlugins()) { Log.e(TAG, "TerminTransformer not initialized yet, cannot retrieve event list");
if (plugin instanceof TerminPlugin) {
terminPlugin = (TerminPlugin) plugin;
}
}
if (terminPlugin == null) {
Log.e(TAG, "TerminPlugin not found, cannot retrieve event list");
return Collections.emptyList(); return Collections.emptyList();
} }
List<TerminPlugin.Event> events = terminPlugin.getEvents(); List<TerminTransformer.Event> events = terminTransformer.getEvents();
Log.d(TAG, "Wiki events found: " + events.size()); Log.d(TAG, "Wiki events found: " + events.size());
return events; return events;
} }
@@ -203,14 +195,14 @@ public class CalendarSyncAdapter extends AbstractThreadedSyncAdapter {
* Adds all events from the event list. The first occurrence is in the current year, the events * Adds all events from the event list. The first occurrence is in the current year, the events
* are repeated every year. * are repeated every year.
*/ */
private void addEvents(@NotNull String calendarId, @NotNull List<TerminPlugin.Event> events) { private void addEvents(@NotNull String calendarId, @NotNull List<TerminTransformer.Event> events) {
Log.d(TAG, "Create calendar events"); Log.d(TAG, "Create calendar events");
for (TerminPlugin.Event event : events) { for (TerminTransformer.Event event : events) {
String title = event.description; String title = event.description;
if (title == null) { if (title == null) {
title = PathUtils.extractWebName(event.pagePath); title = PathUtils.extractWebName(event.pagePath);
} }
String description = getContext().getString(R.string.calendar_date) + ": " + TerminPlugin.formatGermanDate(event.dateFields); String description = getContext().getString(R.string.calendar_date) + ": " + TerminTransformer.formatGermanDate(event.dateFields);
String eventId = addEvent(calendarId, event.dateFields.day, event.dateFields.month, event.dateFields.year, title, description); String eventId = addEvent(calendarId, event.dateFields.day, event.dateFields.month, event.dateFields.year, title, description);
if (eventId != null) { if (eventId != null) {
addReminder(eventId); addReminder(eventId);
@@ -20,8 +20,6 @@ package net.moasdawiki.app;
/** /**
* Enthält zentrale Konstanten. * Enthält zentrale Konstanten.
*
* @author Herbert Reiter
*/ */
public abstract class Constants { public abstract class Constants {
public static final String PREFERENCES_SYNC_SERVER_HOST = "sync_server_host"; public static final String PREFERENCES_SYNC_SERVER_HOST = "sync_server_host";
@@ -47,17 +47,16 @@ import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.menu.MenuBuilder; import androidx.appcompat.view.menu.MenuBuilder;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import net.moasdawiki.base.ServiceException; import net.moasdawiki.base.ServiceException;
import net.moasdawiki.base.Settings; import net.moasdawiki.base.Settings;
import net.moasdawiki.plugin.Plugin;
import net.moasdawiki.plugin.PluginService;
import net.moasdawiki.server.HttpRequest; import net.moasdawiki.server.HttpRequest;
import net.moasdawiki.server.HttpResponse; import net.moasdawiki.server.RequestDispatcher;
import net.moasdawiki.service.render.HtmlService; import net.moasdawiki.service.HttpResponse;
import net.moasdawiki.service.repository.RepositoryService; import net.moasdawiki.service.repository.RepositoryService;
import net.moasdawiki.util.EscapeUtils; import net.moasdawiki.util.EscapeUtils;
@@ -77,19 +76,16 @@ import java.util.Map;
/** /**
* Steuert das Verhalten des Hauptfensters inkl. eingebettetem Browser. * Steuert das Verhalten des Hauptfensters inkl. eingebettetem Browser.
*
* @author Herbert Reiter
*/ */
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
private static final String SERVER_BASE_URL = "http://localhost:1/"; private static final String SERVER_BASE_URL = "http://localhost:1/";
private Settings settings;
private RepositoryService repositoryService; private RepositoryService repositoryService;
private PluginService pluginService; private Settings settings;
private HtmlService htmlService;
private SynchronizeWikiClient synchronizeWikiClient; private SynchronizeWikiClient synchronizeWikiClient;
private RequestDispatcher requestDispatcher;
private WebView webview; private WebView webview;
@@ -102,11 +98,10 @@ public class MainActivity extends AppCompatActivity {
// AndroidMainService holen // AndroidMainService holen
WikiEngineApplication app = (WikiEngineApplication) getApplication(); WikiEngineApplication app = (WikiEngineApplication) getApplication();
settings = app.getServiceLocator().getSettings(); repositoryService = app.getRepositoryService();
repositoryService = app.getServiceLocator().getRepositoryService(); settings = app.getSettings();
pluginService = app.getServiceLocator().getPluginService();
htmlService = app.getServiceLocator().getHtmlService();
synchronizeWikiClient = app.getSynchronizeWikiClient(); synchronizeWikiClient = app.getSynchronizeWikiClient();
requestDispatcher = app.getRequestDispatcher();
// eingebetteten Browser konfigurieren // eingebetteten Browser konfigurieren
initWebView(); initWebView();
@@ -177,10 +172,7 @@ public class MainActivity extends AppCompatActivity {
urlPath = urlPath.substring(0, hashPos); urlPath = urlPath.substring(0, hashPos);
} }
// per URL-Mapping das zuständige Plugin aufrufen // dispatch URL path
HttpResponse response;
Plugin plugin = pluginService.getPluginByUrl(urlPath);
if (plugin != null) {
HttpRequest httpRequest = new HttpRequest(); HttpRequest httpRequest = new HttpRequest();
httpRequest.clientIP = InetAddress.getLocalHost(); httpRequest.clientIP = InetAddress.getLocalHost();
httpRequest.httpHeader = Collections.emptyMap(); httpRequest.httpHeader = Collections.emptyMap();
@@ -189,20 +181,11 @@ public class MainActivity extends AppCompatActivity {
httpRequest.urlPath = urlPath; httpRequest.urlPath = urlPath;
httpRequest.urlParameters = convertParameters(uri); httpRequest.urlParameters = convertParameters(uri);
httpRequest.httpBody = new byte[0]; httpRequest.httpBody = new byte[0];
HttpResponse response = requestDispatcher.handleRequest(httpRequest);
response = plugin.handleRequest(httpRequest);
if (response == null) {
response = htmlService.generateErrorPage(404, "wiki.plugin.handleRequest.notsupported", plugin.getClass().getName());
}
} else {
// unbekannte URL
response = htmlService.generateErrorPage(404, "wiki.server.url.unmapped", urlPath);
}
// Antwortdaten einspeisen // Antwortdaten einspeisen
InputStream responseData = new ByteArrayInputStream(response.getContent()); InputStream responseData = new ByteArrayInputStream(response.content);
return new WebResourceResponse(response.getContentType(), return new WebResourceResponse(response.contentType, "UTF-8", responseData);
"UTF-8", responseData);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -256,30 +239,29 @@ public class MainActivity extends AppCompatActivity {
// automatically handle clicks on the Home/Up button, so long // automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml. // as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) { int itemId = item.getItemId();
case R.id.action_synchronize: if (itemId == R.id.action_synchronize) {
synchronizeServer(); synchronizeServer();
return true; return true;
case R.id.action_startpage: } else if (itemId == R.id.action_startpage) {
loadUrl(SERVER_BASE_URL); loadUrl(SERVER_BASE_URL);
return true; return true;
case R.id.action_settings: } else if (itemId == R.id.action_settings) {
showSettingsDialog(); showSettingsDialog();
return true; return true;
case R.id.action_help: } else if (itemId == R.id.action_help) {
String pagePathHelp = getWikiserverHelpUrl(); String pagePathHelp = getWikiserverHelpUrl();
loadUrl(pagePathHelp); loadUrl(pagePathHelp);
return true; return true;
case R.id.action_about: } else if (itemId == R.id.action_about) {
showAboutDialog(); showAboutDialog();
return true; return true;
default:
return super.onOptionsItemSelected(item);
} }
return super.onOptionsItemSelected(item);
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NotNull String[] permissions, @NotNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d(TAG, "Permission granted by user: requestCode=" + requestCode Log.d(TAG, "Permission granted by user: requestCode=" + requestCode
+ ", permissions=" + Arrays.toString(permissions) + ", grantResults=" + Arrays.toString(grantResults)); + ", permissions=" + Arrays.toString(permissions) + ", grantResults=" + Arrays.toString(grantResults));
super.onRequestPermissionsResult(requestCode, permissions, grantResults); super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@@ -307,15 +289,15 @@ public class MainActivity extends AppCompatActivity {
} }
} }
public void onConfigurationHintClicked(@SuppressWarnings("unused") View view) { public void onConfigurationHintClicked(View view) {
showSettingsDialog(); showSettingsDialog();
} }
public void onSynchronizeHintClicked(@SuppressWarnings("unused") View view) { public void onSynchronizeHintClicked(View view) {
synchronizeServer(); synchronizeServer();
} }
public void onSearch(@SuppressWarnings("unused") View view) { public void onSearch(View view) {
EditText searchInput = findViewById(R.id.search_input); EditText searchInput = findViewById(R.id.search_input);
String query = searchInput.getText().toString(); String query = searchInput.getText().toString();
query = query.trim(); query = query.trim();
@@ -455,8 +437,6 @@ public class MainActivity extends AppCompatActivity {
/** /**
* Synchronisiert mit dem Wikiserver in einem separaten Thread. * Synchronisiert mit dem Wikiserver in einem separaten Thread.
*/ */
@SuppressLint("StaticFieldLeak")
@SuppressWarnings("NonStaticInnerClassInSecureContext")
private class SyncNowTask extends AsyncTask<Void, ProgressData, Integer> implements SynchronizeWikiClient.ProgressFeedback { private class SyncNowTask extends AsyncTask<Void, ProgressData, Integer> implements SynchronizeWikiClient.ProgressFeedback {
@Nullable @Nullable
@@ -29,20 +29,9 @@ import androidx.preference.PreferenceManager;
import net.moasdawiki.base.Logger; import net.moasdawiki.base.Logger;
import net.moasdawiki.base.ServiceException; import net.moasdawiki.base.ServiceException;
import net.moasdawiki.base.Settings; import net.moasdawiki.base.Settings;
import net.moasdawiki.plugin.ServiceLocator;
import net.moasdawiki.plugin.sync.AbstractSyncXml;
import net.moasdawiki.plugin.sync.CheckSessionResponseXml;
import net.moasdawiki.plugin.sync.CheckSessionXml;
import net.moasdawiki.plugin.sync.CreateSessionResponseXml;
import net.moasdawiki.plugin.sync.CreateSessionXml;
import net.moasdawiki.plugin.sync.ErrorResponseXml;
import net.moasdawiki.plugin.sync.ListModifiedFilesResponseXml;
import net.moasdawiki.plugin.sync.ListModifiedFilesXml;
import net.moasdawiki.plugin.sync.ReadFileResponseXml;
import net.moasdawiki.plugin.sync.ReadFileXml;
import net.moasdawiki.plugin.sync.SingleFileXml;
import net.moasdawiki.service.repository.AnyFile; import net.moasdawiki.service.repository.AnyFile;
import net.moasdawiki.service.repository.RepositoryService; import net.moasdawiki.service.repository.RepositoryService;
import net.moasdawiki.service.sync.*;
import net.moasdawiki.util.DateUtils; import net.moasdawiki.util.DateUtils;
import net.moasdawiki.util.xml.XmlGenerator; import net.moasdawiki.util.xml.XmlGenerator;
import net.moasdawiki.util.xml.XmlParser; import net.moasdawiki.util.xml.XmlParser;
@@ -67,8 +56,6 @@ import java.util.Enumeration;
/** /**
* Sucht einen Wikiserver in Netzwerk und synchronisiert alle Wikidateien * Sucht einen Wikiserver in Netzwerk und synchronisiert alle Wikidateien
* im eigenen Repository.. * im eigenen Repository..
*
* @author Herbert Reiter
*/ */
public class SynchronizeWikiClient { public class SynchronizeWikiClient {
@@ -85,13 +72,15 @@ public class SynchronizeWikiClient {
@NotNull @NotNull
private final RepositoryService repositoryService; private final RepositoryService repositoryService;
@NotNull @NotNull
private final SecureRandom random = new SecureRandom(); private final SecureRandom random;
public SynchronizeWikiClient(@NotNull Context mContext, @NotNull ServiceLocator serviceLocator) { public SynchronizeWikiClient(@NotNull Context mContext, @NotNull Logger logger, @NotNull Settings settings,
@NotNull RepositoryService repositoryService) {
this.mContext = mContext; this.mContext = mContext;
this.logger = serviceLocator.getLogger(); this.logger = logger;
this.settings = serviceLocator.getSettings(); this.settings = settings;
this.repositoryService = serviceLocator.getRepositoryService(); this.repositoryService = repositoryService;
this.random = new SecureRandom();
} }
/** /**
@@ -23,58 +23,88 @@ import android.app.Application;
import net.moasdawiki.base.Logger; import net.moasdawiki.base.Logger;
import net.moasdawiki.base.Messages; import net.moasdawiki.base.Messages;
import net.moasdawiki.base.Settings; import net.moasdawiki.base.Settings;
import net.moasdawiki.plugin.PluginService; import net.moasdawiki.server.RequestDispatcher;
import net.moasdawiki.plugin.ServiceLocator; import net.moasdawiki.service.handler.EditorHandler;
import net.moasdawiki.service.handler.FileDownloadHandler;
import net.moasdawiki.service.handler.SearchHandler;
import net.moasdawiki.service.handler.ViewPageHandler;
import net.moasdawiki.service.render.HtmlService; import net.moasdawiki.service.render.HtmlService;
import net.moasdawiki.service.repository.FilesystemRepositoryService;
import net.moasdawiki.service.repository.RepositoryService; import net.moasdawiki.service.repository.RepositoryService;
import net.moasdawiki.service.search.SearchService; import net.moasdawiki.service.search.SearchService;
import net.moasdawiki.service.transform.IncludePageTransformer;
import net.moasdawiki.service.transform.KontaktseiteTransformer;
import net.moasdawiki.service.transform.TerminTransformer;
import net.moasdawiki.service.transform.TransformWikiPage;
import net.moasdawiki.service.transform.TransformerService;
import net.moasdawiki.service.transform.WikiTagsTransformer;
import net.moasdawiki.service.wiki.WikiService; import net.moasdawiki.service.wiki.WikiService;
import net.moasdawiki.service.wiki.WikiServiceImpl;
import java.io.File; import java.io.File;
/** /**
* Verwaltet den Lebenszyklus der Wiki Engine. Muss außerhalb der Activities erfolgen, weil diese * Main control of the wiki App.
* z.B. beim Drehen des Bildschirm neu erzeugt werden.
* *
* @author Herbert Reiter * Must be run globally for the App, i.e. outside of an activity.
*/ */
public class WikiEngineApplication extends Application { public class WikiEngineApplication extends Application {
private static final String REPOSITORY_ROOT_PATH_DEFAULT = "repository";
private Logger logger; private Logger logger;
private ServiceLocator serviceLocator; private RepositoryService repositoryService;
private Settings settings;
private Messages messages;
private WikiService wikiService;
private SynchronizeWikiClient synchronizeWikiClient; private SynchronizeWikiClient synchronizeWikiClient;
private TerminTransformer terminTransformer;
private RequestDispatcher requestDispatcher;
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
logger = new Logger(System.out); logger = new Logger(System.out);
logger.write("MoasdaWiki app starting"); logger.write("MoasdaWiki App starting");
File internalStorageRepositoryRoot = new File(getFilesDir(), "repository"); File internalStorageRepositoryRoot = new File(getFilesDir(), REPOSITORY_ROOT_PATH_DEFAULT);
RepositoryService repositoryService = new FilesystemRepositoryService(logger, internalStorageRepositoryRoot);
// basic services
repositoryService = new RepositoryService(logger, internalStorageRepositoryRoot);
repositoryService.init(); repositoryService.init();
WikiService wikiService = new WikiServiceImpl(logger, repositoryService); settings = new Settings(logger, repositoryService, Settings.getConfigFileServer());
SearchService searchService = new SearchService(logger, repositoryService, wikiService, true); messages = new Messages(logger, settings, repositoryService);
Settings settings = new AndroidSettings(logger, repositoryService, AndroidSettings.getConfigFileApp()); wikiService = new WikiService(logger, repositoryService);
Messages messages = new Messages(logger, settings, repositoryService); SearchService searchService = new SearchService(logger, repositoryService, wikiService, false);
PluginService pluginService = new PluginService(logger, settings);
HtmlService htmlService = new HtmlService(logger, settings, messages, wikiService, pluginService);
serviceLocator = new ServiceLocator(logger, settings, messages, repositoryService, wikiService, htmlService, searchService, pluginService);
pluginService.loadPlugins(serviceLocator); // App: use SynchronizeWikiClient instead of SynchronizationService
synchronizeWikiClient = new SynchronizeWikiClient(this, logger, settings, repositoryService);
synchronizeWikiClient = new SynchronizeWikiClient(this, serviceLocator); // transformers
// do not run the SynchronizationPageTransformer
IncludePageTransformer includePageTransformer = new IncludePageTransformer(logger, wikiService);
KontaktseiteTransformer kontaktseiteTransformer = new KontaktseiteTransformer();
terminTransformer = new TerminTransformer(logger, messages, repositoryService, wikiService);
WikiTagsTransformer wikiTagsTransformer = new WikiTagsTransformer(logger, settings, messages, wikiService);
// list of transformers, the order matters
TransformWikiPage[] transformers = {includePageTransformer, kontaktseiteTransformer, terminTransformer, wikiTagsTransformer};
TransformerService transformerService = new TransformerService(transformers);
// more services
HtmlService htmlService = new HtmlService(logger, settings, messages, wikiService, transformerService);
// HTTP handlers
ViewPageHandler viewPageHandler = new ViewPageHandler(logger, settings, wikiService, htmlService);
SearchHandler searchHandler = new SearchHandler(logger, settings, messages, wikiService, searchService, htmlService);
EditorHandler editorHandler = new EditorHandler(logger, settings, messages, repositoryService, wikiService, transformerService, htmlService);
FileDownloadHandler fileDownloadHandler = new FileDownloadHandler(logger, settings, repositoryService, htmlService);
requestDispatcher = new RequestDispatcher(htmlService, viewPageHandler,
searchHandler, editorHandler, fileDownloadHandler, null);
} }
public void resetServices() { public void resetServices() {
serviceLocator.getRepositoryService().rebuildCache(); repositoryService.rebuildCache();
serviceLocator.getWikiService().reset(); wikiService.reset();
serviceLocator.getSettings().reset(); settings.reset();
serviceLocator.getMessages().reset(); messages.reset();
serviceLocator.getPluginService().loadPlugins(serviceLocator);
} }
@Override @Override
@@ -83,11 +113,23 @@ public class WikiEngineApplication extends Application {
super.onTerminate(); super.onTerminate();
} }
public ServiceLocator getServiceLocator() { public RepositoryService getRepositoryService() {
return serviceLocator; return repositoryService;
}
public Settings getSettings() {
return settings;
}
public TerminTransformer getTerminTransformer() {
return terminTransformer;
} }
public SynchronizeWikiClient getSynchronizeWikiClient() { public SynchronizeWikiClient getSynchronizeWikiClient() {
return synchronizeWikiClient; return synchronizeWikiClient;
} }
public RequestDispatcher getRequestDispatcher() {
return requestDispatcher;
}
} }