+import org.argeo.app.ux.AppUi;
+import org.argeo.app.ux.SuiteUxEvent;
+import org.argeo.cms.LocaleUtils;
+import org.argeo.cms.Localized;
+import org.argeo.cms.swt.CmsSwtUtils;
+import org.argeo.cms.swt.acr.SwtUiProvider;
+import org.argeo.cms.swt.dialogs.CmsFeedback;
+import org.argeo.cms.util.LangUtils;
+import org.argeo.cms.ux.CmsUxUtils;
+import org.argeo.eclipse.ui.specific.UiContext;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
+import org.eclipse.swt.widgets.Composite;
+import org.osgi.framework.Constants;
+
+/** The Argeo Suite App. */
+public class SwtArgeoApp extends AbstractArgeoApp implements CmsEventSubscriber {
+ private final static CmsLog log = CmsLog.getLog(SwtArgeoApp.class);
+
+ public final static String PUBLIC_BASE_PATH_PROPERTY = "publicBasePath";
+ public final static String DEFAULT_UI_NAME_PROPERTY = "defaultUiName";
+ public final static String DEFAULT_THEME_ID_PROPERTY = "defaultThemeId";
+ public final static String DEFAULT_LAYER_PROPERTY = "defaultLayer";
+ public final static String SHARED_PID_PREFIX_PROPERTY = "sharedPidPrefix";
+
+ private final static String LOGIN = "login";
+ private final static String HOME_STATE = "~";
+
+ private String publicBasePath = null;
+
+ private String appPid;
+ private String pidPrefix;
+ private String sharedPidPrefix;
+
+// private String headerPid;
+// private String footerPid;
+// private String leadPanePid;
+// private String adminLeadPanePid;
+// private String loginScreenPid;
+
+ private String defaultUiName = "app";
+ private String adminUiName = "admin";
+
+ // FIXME such default names make refactoring more dangerous
+ @Deprecated
+ private String defaultLayerPid = "argeo.suite.ui.dashboardLayer";
+ @Deprecated
+ private String defaultThemeId = "org.argeo.app.theme.default";
+
+ // TODO use QName as key for byType
+ private Map<String, RankedObject<SwtUiProvider>> uiProvidersByPid = Collections.synchronizedMap(new HashMap<>());
+ private Map<String, RankedObject<SwtUiProvider>> uiProvidersByType = Collections.synchronizedMap(new HashMap<>());
+ private Map<String, RankedObject<SwtAppLayer>> layersByPid = Collections.synchronizedSortedMap(new TreeMap<>());
+ private Map<String, RankedObject<SwtAppLayer>> layersByType = Collections.synchronizedSortedMap(new TreeMap<>());
+
+// private CmsUserManager cmsUserManager;
+
+ // TODO make more optimal or via CmsSession/CmsView
+ private Map<String, SwtAppUi> managedUis = Collections.synchronizedMap(new HashMap<>());
+
+ // ACR
+ private ContentRepository contentRepository;
+ private AppUserState appUserState;
+ // JCR
+// private Repository repository;
+
+ public void start(Map<String, Object> properties) {
+ for (SuiteUxEvent event : SuiteUxEvent.values()) {
+ getCmsContext().getCmsEventBus().addEventSubscriber(event.topic(), this);
+ }
+
+ if (log.isDebugEnabled())
+ log.info("Argeo Suite App started");
+
+ if (properties.containsKey(DEFAULT_UI_NAME_PROPERTY))
+ defaultUiName = LangUtils.get(properties, DEFAULT_UI_NAME_PROPERTY);
+ if (properties.containsKey(DEFAULT_THEME_ID_PROPERTY))
+ defaultThemeId = LangUtils.get(properties, DEFAULT_THEME_ID_PROPERTY);
+ if (properties.containsKey(DEFAULT_LAYER_PROPERTY))
+ defaultLayerPid = LangUtils.get(properties, DEFAULT_LAYER_PROPERTY);
+ sharedPidPrefix = LangUtils.get(properties, SHARED_PID_PREFIX_PROPERTY);
+ publicBasePath = LangUtils.get(properties, PUBLIC_BASE_PATH_PROPERTY);
+
+ if (properties.containsKey(Constants.SERVICE_PID)) {
+ appPid = properties.get(Constants.SERVICE_PID).toString();
+ int lastDotIndex = appPid.lastIndexOf('.');
+ if (lastDotIndex >= 0) {
+ pidPrefix = appPid.substring(0, lastDotIndex);
+ }
+ } else {
+ // TODO does it make sense to accept that?
+ appPid = "<unknown>";
+ }
+
+ Objects.requireNonNull(contentRepository, "Content repository must be provided");
+ Objects.requireNonNull(appUserState, "App user state must be provided");
+// if (pidPrefix == null)
+// throw new IllegalArgumentException("PID prefix must be set.");
+
+// headerPid = pidPrefix + "header";
+// footerPid = pidPrefix + "footer";
+// leadPanePid = pidPrefix + "leadPane";
+// adminLeadPanePid = pidPrefix + "adminLeadPane";
+// loginScreenPid = pidPrefix + "loginScreen";
+
+ }
+
+ public void stop(Map<String, Object> properties) {
+ for (SwtAppUi ui : managedUis.values())
+ if (!ui.isDisposed() && !ui.getDisplay().isDisposed()) {
+ ui.getDisplay().syncExec(() -> ui.dispose());
+ }
+ managedUis.clear();
+ if (log.isDebugEnabled())
+ log.info("Argeo Suite App stopped");
+
+ }