diff --git a/.gitignore b/.gitignore index 32858aa..a30fb2d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,11 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +.metadata/ +RemoteSystemsTempFiles/ +WebSphere Application Server Liberty Profile 8554/ +WebSphere Application Server Liberty Profile 8554 - CrossWorlds/ +org.openntf.xworlds.webapp.j2eeenabler/bin/META-INF/MANIFEST.MF +org.openntf.xworlds.webapp.j2eeenabler/bin/META-INF/web-fragment.xml +org.openntf.xworlds.core/.settings/org.eclipse.ltk.core.refactoring.prefs +org.openntf.xworlds.oda/build-local.properties diff --git a/CrossWorlds Docs/.project b/CrossWorlds Docs/.project new file mode 100644 index 0000000..be38536 --- /dev/null +++ b/CrossWorlds Docs/.project @@ -0,0 +1,11 @@ + + + CrossWorlds Docs + + + + + + + + diff --git a/CrossWorlds Docs/presentations/20150102-Introducing CrossWorlds.pptx b/CrossWorlds Docs/presentations/20150102-Introducing CrossWorlds.pptx new file mode 100644 index 0000000..22950cb Binary files /dev/null and b/CrossWorlds Docs/presentations/20150102-Introducing CrossWorlds.pptx differ diff --git a/CrossWorldsDistro/.project b/CrossWorldsDistro/.project new file mode 100644 index 0000000..e93c501 --- /dev/null +++ b/CrossWorldsDistro/.project @@ -0,0 +1,11 @@ + + + CrossWorldsDistro + + + + + + + + diff --git a/CrossWorldsDistro/Copy CrossWorlds to staging directory.launch b/CrossWorldsDistro/Copy CrossWorlds to staging directory.launch new file mode 100644 index 0000000..1089f20 --- /dev/null +++ b/CrossWorldsDistro/Copy CrossWorlds to staging directory.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/CrossWorldsDistro/README.TXT b/CrossWorldsDistro/README.TXT new file mode 100644 index 0000000..e69de29 diff --git a/CrossWorldsDistro/apps/README.TXT b/CrossWorldsDistro/apps/README.TXT new file mode 100644 index 0000000..fd760d8 --- /dev/null +++ b/CrossWorldsDistro/apps/README.TXT @@ -0,0 +1,3 @@ +This folder contains applications from CrossWorlds + +- CrossWorldsDemo.war is the Sampler application \ No newline at end of file diff --git a/CrossWorldsDistro/etc/setenv.bat.dist b/CrossWorldsDistro/etc/setenv.bat.dist new file mode 100644 index 0000000..e69de29 diff --git a/CrossWorldsDistro/etc/setenv.sh.dist b/CrossWorldsDistro/etc/setenv.sh.dist new file mode 100644 index 0000000..e69de29 diff --git a/CrossWorldsDistro/etc/xworlds-instance.properties b/CrossWorldsDistro/etc/xworlds-instance.properties new file mode 100644 index 0000000..d792720 --- /dev/null +++ b/CrossWorldsDistro/etc/xworlds-instance.properties @@ -0,0 +1,20 @@ +# Development / build params + +# dev.clean controls the build process. If true it completely wipes the build directory +dev.clean=false + +# CrossWorlds Paths + +xworlds.install.root=D:/dev/CrossWorldsBuild +xworlds.server.name=CrossWorlds + +# WebSphere Liberty related paths + +wlp.product.dir=D:/dev/liberty_8554/wlp +wlp.user.dir=${wlp.product.dir}/usr + +# Domino / Notes related paths + +domino.product.dir= +domino.data.dir=${domino.product.dir}/data + diff --git a/CrossWorldsDistro/etc/xworlds-instance.properties.dist b/CrossWorldsDistro/etc/xworlds-instance.properties.dist new file mode 100644 index 0000000..6b7a46d --- /dev/null +++ b/CrossWorldsDistro/etc/xworlds-instance.properties.dist @@ -0,0 +1,14 @@ +# CrossWorlds Paths + +xworlds.install.root= + +# WebSphere Liberty related paths + +wlp.product.dir= +wlp.user.dir=${wlp.product.dir}/usr + +# Domino / Notes related paths + +domino.product.dir= +domino.data.dir=${domino.product.dir}/data + diff --git a/CrossWorldsDistro/xworlds.here b/CrossWorldsDistro/xworlds.here new file mode 100644 index 0000000..62c84af --- /dev/null +++ b/CrossWorldsDistro/xworlds.here @@ -0,0 +1 @@ +This placeholder is a signpost for the CrossWorlds installation directory \ No newline at end of file diff --git a/Install Notes PW.md b/Install Notes PW.md new file mode 100644 index 0000000..db46bc6 --- /dev/null +++ b/Install Notes PW.md @@ -0,0 +1,53 @@ +===================================== + +Updating ODA +1. Remove from feature project +2. Remove jars from build path in org.xworlds.oda +3. Delete jars +4. Update build.properties +5. Run build.xml +6. Delete source jars +7. Add others to build path +8. In MANIFEST.MF update version number and add jars to bin. Also update Bundle-ClassPath +9. In Project > Properties, add all jars to Order and Export tab +10. Right-click on feature and choose Update Feature to republish to the server + +===================================== + +https://developer.ibm.com/wasdev/downloads/liberty-profile-using-non-eclipse-environments/ +1. Download or start Eclipse Mars IDE for Java EE Developers. Typically, I recommend a separate installation for CrossWorlds (as far any development environment) +2. Install Eclipse plugins (go to Help > Eclipse Marketplace... and search for "Liberty". Install "IBM Websphere Application Server Developer Tools for Mars" +3. Install "Vaadin plugin for Eclipse 2.3.5.20150923" +4. Restart Eclipse + +5. Amend Maven Settings in Eclipse to add was-liberty (see screenshots) +6. In Java-EE perspective, on Servers tab, right-click and select New > Server. Select Websphere Application Server Liberty. Click Next. Change name to "Websphere Application Server Liberty Profile", select "Install from an archive or a repository". +7. (optional) Click "Configure JREs..." and add Java 6 and Java 7 (if not already installed, you will need to download from Oracle website) +8. Click Next. Enter a destination path in which to install the liberty server, e.g. C:\Program Files\IBM\Liberty. Select "Download and install a new runtime environment from ibm.com" and choose the latest "WAS Liberty with Java EE 7 Web Profile" +(9. In "Install Additional Content", select "OSGi debug console". Click Next. Accept terms and conditions. Finish. Liberty will be extracted and installed.) +10. In Window > Preferences, go to Run/Debug > String Substitution. Create a new entry called was_liberty_root and point to the folder for liberty (the folder will contain subfolders bin, clients, dev, java etc) +11. Right-click on Websphere Application Server Liberty Profile and select New > Folder. Create a new folder called "extension". Right-click on the extension folder and select New > Folder. Create a new folder called "lib". +12. Right-click on the server in the Servers view and select New > Server Environment File > server.env. Add a variable called PATH with a value mapping to your Domino server. E.g. PATH=C:\Program Files\IBM\Domino. +13. Add a file under default server called bootstrap.properties. Add a variable xworlds.developermode=true. (Here is where you would also define the port for the osgi console - osgi.console=5676) + +14. Right-click in the Enterprise Explorer pane and select Import..., then General > Existing Projects into Workspace. Select the CrossWorlds download, ensuring Copy projects into workspace is ticked. +16. In Window > Preferences, go to Plug-in Development > Target Platform and select "Websphere Application Server Liberty Profile with SPI". + +17. Open org.openntf.xworlds.dominodeps project. Open dependencies.txt and note the five external jars required. Copy and paste them into BundleContent folder in org.openntf.xworlds.dominodeps + notes.jar is in jvm\lib\ext + com.ibm.icu_3.8.1.v20120530 is in Domino\osgi\rcp\eclipse\plugins + com.ibm.icu.base_3.8.1.v20080530 is in Domino\osgi\rcp\eclipse\plugins + lwpd.commons.jar is in Domino\osgi\shared\eclipse\plugins\com.ibm.commons_9.0.1.20131004-1200 + lwpd.domino.napi.jar is in Domino\osgi\shared\eclipse\plugins\com.ibm.domino.napi_9.0.1.20131004-1200 +18. Right-click on org.openntf.xworlds.dominodeps and select New > Folder. Create a new folder called src. + +19. Download ODA zip file and extract contents to e.g. C:\temp\oda +20. Open org.openntf.xworlds.oda. In build.properties (top-level file) amend the variables according to notes, so the first maps to the plugins folder of the update site (using "/", not "\") and the second is the unique date-time suffix of the main org.openntf.domino.... jars. +21. Right-click on org.openntf.xworlds.oda and select New > Folder. Create a new folder called src. +22. Right-click on build.xml and select Run As > Ant Build.... Ensure the JRE (on JRE tab) is greater than JRE1.6. Once completed, select org.openntf.xworlds.oda and press F5 to refresh the files. + +23. Right-click on org.openntf.xworlds.features.server and select Install Feature.... (If it says it's already loaded, use Update Feature instead) +24. Open servers > default server > server.xml and click on Feature Manager. Click Add... and select usr:CrossWorlds-1.0. Repeat for cdi-1.2, jaxrs-2.0, localConnector-1.0. + +25. Right-click and select Import > Maven Projects and navigate to folder containing pom.xml of OdaDemoAppLiberty. +26. If you receive errors with org.openntf.xworlds.webapp.j2eeenabler, try closing the project and re-opening it. If that doesn't fix it, check Maven Settings in Eclipse for repository location. Then check org/openntf/xworlds/webapp/j2eenabler folder exists. If not, extract from attached, then close and re-open the project. diff --git a/README.md b/README.md index c6b805c..1171511 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,13 @@ -CrossWorlds -=========== +# CrossWorlds -The CrossWorlds Project for IBM Domino and OpenNTF ODA +The CrossWorlds Project for IBM Domino and OpenNTF ODA brings together: + +- Domino +- OpenNTF Domino API +- WebSphere Liberty + +## Repository structure + +## Documentation + +For an introduction: http://www.slideshare.net/DanieleVistalli/introducing-crossworlds-for-ibm-domino diff --git a/branch.md b/branch.md new file mode 100644 index 0000000..367140e --- /dev/null +++ b/branch.md @@ -0,0 +1,11 @@ +# About the development branch + +This branch is the place where development for CrossWorls 0.5 is taking place. + +Objectives for this branch: + +- Build the first releasable version of CrossWorlds +- Provide configuration samples +- Provide documentation on the supported features inherited from OpenNTF Domino Api +- Provide documentation on additional features enabled by CrossWorlds +- Sampler application with groovy console diff --git a/org.openntf.xworlds.core/.classpath b/org.openntf.xworlds.core/.classpath new file mode 100644 index 0000000..8f6f272 --- /dev/null +++ b/org.openntf.xworlds.core/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.openntf.xworlds.core/.gitignore b/org.openntf.xworlds.core/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/org.openntf.xworlds.core/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/org.openntf.xworlds.core/.project b/org.openntf.xworlds.core/.project new file mode 100644 index 0000000..06ad75f --- /dev/null +++ b/org.openntf.xworlds.core/.project @@ -0,0 +1,48 @@ + + + org.openntf.xworlds.core + + + org.openntf.xworlds.dominodeps + org.openntf.xworlds.oda + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.zeroturnaround.eclipse.rebelXmlBuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + org.zeroturnaround.eclipse.jrebelNature + + diff --git a/org.openntf.xworlds.core/.settings/com.ibm.etools.aries.core.prefs b/org.openntf.xworlds.core/.settings/com.ibm.etools.aries.core.prefs new file mode 100644 index 0000000..7dd2046 --- /dev/null +++ b/org.openntf.xworlds.core/.settings/com.ibm.etools.aries.core.prefs @@ -0,0 +1,4 @@ +com.ibm.etools.aries.all=applied +com.ibm.etools.aries.java.jars=applied +com.ibm.etools.aries.web.export=applied +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.core/.settings/com.ibm.etools.webtools.packagepreferences.prefs b/org.openntf.xworlds.core/.settings/com.ibm.etools.webtools.packagepreferences.prefs new file mode 100644 index 0000000..60f37f5 --- /dev/null +++ b/org.openntf.xworlds.core/.settings/com.ibm.etools.webtools.packagepreferences.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +use-project-settings=false diff --git a/org.openntf.xworlds.core/.settings/com.ibm.ws.st.prefs b/org.openntf.xworlds.core/.settings/com.ibm.ws.st.prefs new file mode 100644 index 0000000..e2dc526 --- /dev/null +++ b/org.openntf.xworlds.core/.settings/com.ibm.ws.st.prefs @@ -0,0 +1,3 @@ +com.ibm.ws.st.feature.blueprint-1.0=never +com.ibm.ws.st.feature.servlet-3.1=never +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.core/.settings/org.eclipse.jdt.core.prefs b/org.openntf.xworlds.core/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..ef8a789 --- /dev/null +++ b/org.openntf.xworlds.core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/org.openntf.xworlds.core/.settings/org.eclipse.pde.core.prefs b/org.openntf.xworlds.core/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..9e852b9 --- /dev/null +++ b/org.openntf.xworlds.core/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,6 @@ +BUNDLE_ROOT_PATH=BundleContent +eclipse.preferences.version=1 +manifest.exportWizard=com.ibm.etools.aries.bundle.export +manifest.launchShortcuts=org.eclipse.wst.server.launchShortcut,org.eclipse.wst.server.launchShortcut +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/org.openntf.xworlds.core/.settings/org.eclipse.wst.common.component b/org.openntf.xworlds.core/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..cffb276 --- /dev/null +++ b/org.openntf.xworlds.core/.settings/org.eclipse.wst.common.component @@ -0,0 +1,6 @@ + + + + + + diff --git a/org.openntf.xworlds.core/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.openntf.xworlds.core/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..5289bad --- /dev/null +++ b/org.openntf.xworlds.core/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.openntf.xworlds.core/BundleContent/META-INF/MANIFEST.MF b/org.openntf.xworlds.core/BundleContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000..4191333 --- /dev/null +++ b/org.openntf.xworlds.core/BundleContent/META-INF/MANIFEST.MF @@ -0,0 +1,301 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.openntf.xworlds.core +Bundle-SymbolicName: org.openntf.xworlds.core;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.openntf.xworlds.core.Activator +Export-Package: + org.openntf.xworlds.appservers.lifecycle, + org.openntf.xworlds.appservers.webapp, + org.openntf.xworlds.appservers.webapp.config, + org.openntf.xworlds.appservers.webapp.security, + org.openntf.xworlds.appservers.webapp.utils, + org.openntf.xworlds.core, + org.openntf.xworlds.xots +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: Acme, + Acme.JPM.Encoders, + com.google.common.annotations, + com.google.common.base, + com.google.common.base.internal, + com.google.common.cache, + com.google.common.collect, + com.google.common.escape, + com.google.common.eventbus, + com.google.common.hash, + com.google.common.html, + com.google.common.io, + com.google.common.math, + com.google.common.net, + com.google.common.primitives, + com.google.common.reflect, + com.google.common.util.concurrent, + com.google.common.xml, + com.google.thirdparty.publicsuffix, + com.ibm.commons, + com.ibm.commons.extension, + com.ibm.commons.log, + com.ibm.commons.log.eclipse, + com.ibm.commons.log.jdk, + com.ibm.commons.platform, + com.ibm.commons.preferences, + com.ibm.commons.preferences.eclipse, + com.ibm.commons.util, + com.ibm.commons.util.io, + com.ibm.commons.util.io.base64, + com.ibm.commons.util.io.json, + com.ibm.commons.util.io.json.parser, + com.ibm.commons.util.io.json.util, + com.ibm.commons.util.print, + com.ibm.commons.util.profiler, + com.ibm.designer.domino.napi, + com.ibm.designer.domino.napi.design, + com.ibm.designer.domino.napi.dxl, + com.ibm.designer.domino.napi.struct, + com.ibm.designer.domino.napi.util, + com.ibm.domino.napi, + com.ibm.domino.napi.c, + com.ibm.domino.napi.c.callback, + com.ibm.domino.napi.c.data, + com.ibm.domino.napi.c.html, + com.ibm.domino.napi.c.ref, + com.ibm.domino.napi.c.ssl, + com.ibm.domino.napi.c.struct, + com.ibm.domino.napi.c.util, + com.ibm.domino.napi.c.xsp, + com.ibm.domino.napi.internal.c, + com.ibm.domino.napi.ssl, + com.ibm.domino.napi.util, + com.ibm.icu.impl, + com.ibm.icu.impl.data, + com.ibm.icu.impl.duration, + com.ibm.icu.impl.duration.impl, + com.ibm.icu.lang, + com.ibm.icu.math, + com.ibm.icu.text, + com.ibm.icu.util, + com.ibm.sslight, + com.ibm.sslight.tools, + com.ibm.websphere.security;version="1.1.0", + com.tinkerpop.blueprints, + com.tinkerpop.blueprints.util, + com.tinkerpop.blueprints.util.io, + com.tinkerpop.blueprints.util.wrappers, + com.tinkerpop.blueprints.util.wrappers.event, + com.tinkerpop.blueprints.util.wrappers.event.listener, + com.tinkerpop.blueprints.util.wrappers.id, + com.tinkerpop.blueprints.util.wrappers.partition, + com.tinkerpop.blueprints.util.wrappers.readonly, + com.tinkerpop.blueprints.util.wrappers.wrapped, + com.tinkerpop.frames, + com.tinkerpop.frames.annotations, + com.tinkerpop.frames.annotations.gremlin, + com.tinkerpop.frames.core, + com.tinkerpop.frames.modules, + com.tinkerpop.frames.modules.javahandler, + com.tinkerpop.frames.modules.typedgraph, + com.tinkerpop.frames.structures, + com.tinkerpop.frames.util, + com.tinkerpop.gremlin, + com.tinkerpop.gremlin.java, + com.tinkerpop.pipes, + com.tinkerpop.pipes.branch, + com.tinkerpop.pipes.filter, + com.tinkerpop.pipes.sideeffect, + com.tinkerpop.pipes.transform, + com.tinkerpop.pipes.util, + com.tinkerpop.pipes.util.iterators, + com.tinkerpop.pipes.util.structures, + javassist, + javassist.bytecode, + javassist.bytecode.analysis, + javassist.bytecode.annotation, + javassist.bytecode.stackmap, + javassist.compiler, + javassist.compiler.ast, + javassist.convert, + javassist.expr, + javassist.runtime, + javassist.scopedpool, + javassist.tools, + javassist.tools.reflect, + javassist.tools.rmi, + javassist.tools.web, + javassist.util.proxy, + javax.annotation, + javax.annotation.concurrent, + javax.annotation.meta, + javax.realtime, + javax.servlet;version="2.6.0", + javax.servlet.http;version="2.6.0", + javolution.context, + javolution.context.internal, + javolution.io, + javolution.lang, + javolution.osgi.internal, + javolution.text, + javolution.text.internal, + javolution.tools, + javolution.util, + javolution.util.function, + javolution.util.internal, + javolution.util.internal.bitset, + javolution.util.internal.collection, + javolution.util.internal.comparator, + javolution.util.internal.map, + javolution.util.internal.map.sorted, + javolution.util.internal.set, + javolution.util.internal.set.sorted, + javolution.util.internal.table, + javolution.util.internal.table.sorted, + javolution.util.service, + javolution.xml, + javolution.xml.internal, + javolution.xml.internal.stream, + javolution.xml.sax, + javolution.xml.stream, + javolution.xml.ws, + junit.extensions, + junit.framework, + junit.runner, + junit.textui, + lotus.domino, + lotus.domino.corba, + lotus.domino.corba.NameAndObjectUPackage, + lotus.domino.cso, + lotus.domino.local, + lotus.domino.util, + lotus.notes, + lotus.notes.addins, + lotus.notes.addins.changeman, + lotus.notes.addins.changeman.control, + lotus.notes.addins.changeman.functions, + lotus.notes.addins.changeman.monitor, + lotus.notes.addins.changeman.roboadmin, + lotus.notes.addins.changeman.workflow, + lotus.notes.addins.daytime, + lotus.notes.addins.dsfclassifier, + lotus.notes.addins.dsflearning, + lotus.notes.addins.guru, + lotus.notes.addins.ispy, + lotus.notes.addins.ispy.net, + lotus.notes.addins.ispy.net.dns, + lotus.notes.addins.ispy.net.portcheck, + lotus.notes.addins.ispy.util, + lotus.notes.addins.rmeval, + lotus.notes.addins.util, + lotus.notes.apps.reports, + lotus.notes.apps.wmsgtrc, + lotus.notes.internal, + lotus.priv.CORBA.iiop, + lotus.priv.CORBA.iiop.ssl, + lotus.priv.CORBA.iiop.sslight, + lotus.priv.CORBA.java.Exception, + lotus.priv.CORBA.portable, + org.eclipse.jdt.internal.junit.runner, + org.eclipse.jdt.internal.junit.runner.junit3, + org.eclipse.jdt.internal.junit4.runner, + org.hamcrest, + org.hamcrest.core, + org.hamcrest.internal, + org.junit, + org.junit.experimental, + org.junit.experimental.categories, + org.junit.experimental.max, + org.junit.experimental.results, + org.junit.experimental.runners, + org.junit.experimental.theories, + org.junit.experimental.theories.internal, + org.junit.experimental.theories.suppliers, + org.junit.internal, + org.junit.internal.builders, + org.junit.internal.matchers, + org.junit.internal.requests, + org.junit.internal.runners, + org.junit.internal.runners.model, + org.junit.internal.runners.rules, + org.junit.internal.runners.statements, + org.junit.matchers, + org.junit.rules, + org.junit.runner, + org.junit.runner.manipulation, + org.junit.runner.notification, + org.junit.runners, + org.junit.runners.model, + org.openntf.arpa, + org.openntf.calendars, + org.openntf.domino, + org.openntf.domino.annotations, + org.openntf.domino.big, + org.openntf.domino.big.impl, + org.openntf.domino.design, + org.openntf.domino.design.impl, + org.openntf.domino.email, + org.openntf.domino.events, + org.openntf.domino.exceptions, + org.openntf.domino.ext, + org.openntf.domino.formula, + org.openntf.domino.graph, + org.openntf.domino.graph2, + org.openntf.domino.graph2.annotations, + org.openntf.domino.graph2.builtin, + org.openntf.domino.graph2.builtin.social, + org.openntf.domino.graph2.builtin.workflow, + org.openntf.domino.graph2.builtin.workflow.definition, + org.openntf.domino.graph2.exception, + org.openntf.domino.graph2.impl, + org.openntf.domino.helpers, + org.openntf.domino.i18n, + org.openntf.domino.impl, + org.openntf.domino.iterators, + org.openntf.domino.junit, + org.openntf.domino.logging, + org.openntf.domino.nsfdata, + org.openntf.domino.nsfdata.impldxl, + org.openntf.domino.nsfdata.impldxl.item, + org.openntf.domino.nsfdata.structs, + org.openntf.domino.nsfdata.structs.cd, + org.openntf.domino.schema, + org.openntf.domino.schema.exceptions, + org.openntf.domino.schema.impl, + org.openntf.domino.schema.types, + org.openntf.domino.session, + org.openntf.domino.tests, + org.openntf.domino.tests.eknori, + org.openntf.domino.tests.jpg, + org.openntf.domino.tests.ntf, + org.openntf.domino.tests.paul, + org.openntf.domino.tests.rpr, + org.openntf.domino.tests.rpr.formula, + org.openntf.domino.tests.xmage, + org.openntf.domino.thread, + org.openntf.domino.transactions, + org.openntf.domino.types, + org.openntf.domino.utils, + org.openntf.domino.utils.xml, + org.openntf.domino.xots, + org.openntf.domino.xots.events, + org.openntf.domino.xsp, + org.openntf.domino.xsp.adapter, + org.openntf.domino.xsp.components, + org.openntf.domino.xsp.config, + org.openntf.domino.xsp.formula, + org.openntf.domino.xsp.helpers, + org.openntf.domino.xsp.junit, + org.openntf.domino.xsp.junit.test, + org.openntf.domino.xsp.model, + org.openntf.domino.xsp.msg, + org.openntf.domino.xsp.readers, + org.openntf.domino.xsp.script, + org.openntf.domino.xsp.session, + org.openntf.domino.xsp.xots, + org.openntf.formula, + org.openntf.formula.annotation, + org.openntf.formula.ast, + org.openntf.formula.function, + org.openntf.formula.impl, + org.openntf.formula.parse, + org.openntf.formula.test, + org.openntf.junit4xpages, + org.openntf.service, + org.osgi.framework diff --git a/org.openntf.xworlds.core/BundleContent/build.properties b/org.openntf.xworlds.core/BundleContent/build.properties new file mode 100644 index 0000000..5f22cdd --- /dev/null +++ b/org.openntf.xworlds.core/BundleContent/build.properties @@ -0,0 +1 @@ +bin.includes = META-INF/ diff --git a/org.openntf.xworlds.core/WASLibertyWithSPI.target b/org.openntf.xworlds.core/WASLibertyWithSPI.target new file mode 100644 index 0000000..1094e6d --- /dev/null +++ b/org.openntf.xworlds.core/WASLibertyWithSPI.target @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/org.openntf.xworlds.core/doc/xworlds-config.md b/org.openntf.xworlds.core/doc/xworlds-config.md new file mode 100644 index 0000000..567caf1 --- /dev/null +++ b/org.openntf.xworlds.core/doc/xworlds-config.md @@ -0,0 +1,11 @@ +# CrossWorlds configurations parameters + +## Settings in notes.ini + +- CROSSWORLDSDEV=true|false controls if CrossWolrds will run in developer mode or not. + +## Settings in bootstrap.properties + +- xworlds.userid.password is the property storing the password to unlock the notes ID to be used with this +CrowsWorlds instance. +- xworlds.developermode=true|false \ No newline at end of file diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/lifecycle/XWorldsManagedThread.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/lifecycle/XWorldsManagedThread.java new file mode 100644 index 0000000..9eae3ab --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/lifecycle/XWorldsManagedThread.java @@ -0,0 +1,96 @@ +package org.openntf.xworlds.appservers.lifecycle; + +import java.util.logging.Logger; + +import javax.servlet.http.HttpServletRequest; + +import lotus.domino.NotesThread; + +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +public class XWorldsManagedThread { + + private static Logger log = Logger.getLogger(XWorldsManagedThread.class.getName()); + + private static class TvDominoRequest { + + private boolean ready = false; + + public void reset() { + ready = false; + } + + public boolean isReady() { + return ready; + } + public void setReady(boolean readyForDomino) { + this.ready = readyForDomino; + } + + } + + static ThreadLocal XWorldsThreadState = new ThreadLocal() { + + @Override + protected TvDominoRequest initialValue() { + return new TvDominoRequest(); + } + + }; + + public static void setupAsDominoThread(HttpServletRequest request) { + + if (XWorldsManager.getInstance().isStarted()) { + + if (! Factory.isStarted()) { // Wait for ODA Factory to beready + int timeout = 30; // Maximum wait time for Factory startup; + while (! Factory.isStarted() && timeout > 0) { + try { + System.out.print("."); + timeout--; + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + if (XWorldsThreadState.get().isReady() == false) { + log.fine("Setting up this thread for domino " + Thread.currentThread().getId() + " / " + Thread.currentThread().getName()); + Factory.initThread(Factory.STRICT_THREAD_CONFIG); + + // Override the default session factory. + Factory.setSessionFactory( Factory.getSessionFactory(SessionType.NATIVE), SessionType.CURRENT); + + NotesThread.sinitThread(); + XWorldsThreadState.get().setReady(true); + } else { + log.severe("Domino already setup for thread " + Thread.currentThread().getId() + " / " + Thread.currentThread().getName()); + } + + } else { + log.severe("The XWorldsManager has not yet been started. Check for information at ...."); + } + + } + + public static void shutdownDominoThread() { + + if (XWorldsManager.getInstance().isStarted()) { + + if (XWorldsThreadState.get().isReady() == true) { + log.fine("Shutting down this thread for domino " + Thread.currentThread().getId() + " / " + Thread.currentThread().getName()); + NotesThread.stermThread(); + Factory.termThread(); + XWorldsThreadState.get().reset(); + } else { + log.severe("ERROR: Domino wasn't setup for thread " + Thread.currentThread().getId() + " / " + Thread.currentThread().getName()); + } + } else { + log.severe("The XWorldsManager has not yet been started. Check for information at ...."); + } + + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/lifecycle/XWorldsManager.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/lifecycle/XWorldsManager.java new file mode 100644 index 0000000..a515c67 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/lifecycle/XWorldsManager.java @@ -0,0 +1,235 @@ +package org.openntf.xworlds.appservers.lifecycle; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.lang.Thread.State; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Logger; + +import org.openntf.domino.utils.Factory; +import org.openntf.domino.xots.Xots; +import org.openntf.xworlds.xots.XotsDominoExecutor; + +import lotus.domino.NotesException; +import lotus.domino.NotesFactory; +import lotus.domino.NotesThread; + +/** + * This Manager class acts as an appserver-wide management service to ensure ODA + * services are just started once.
+ *
+ * The application listener embedded in every XWorlds enabled application will + * startup the engine by calling XWorldsManager.startup()
+ *
+ * The startup code will initialize application tracking code to list all + * enabled applications and to manage monitoring and service reporting and will: + *
    + *
  • Setup a map of initialized "servletContexts" using XWorlds servcices + *
  • Startup Factory.startup() if not already done globally (managing + * concurrency) + *
  • Startup a "locker" NotesThread to ensure domino is loaded for the whole + * execution of the application server. This will eventually be replaced by a + * service similar to ODA's Xots to submit batchs. Ideally XWolds should also + * come to support Java Batch extensions as supported by WAS Libery. + *
+ *
+ * The application listener will even manage XWorldsManager.shutdown() to reduce + * the number of loaded istances and to update monitoring
+ * + * + * + * + * @author Daniele Vistalli + * + */ +public class XWorldsManager { + + private static Logger log = Logger.getLogger(XWorldsManager.class.getName()); + private static XWorldsManager _instance = null; + + private boolean _started = false; + private boolean _napiStarted = false; + + private AtomicInteger xwmStartedCount = new AtomicInteger(0); + private AtomicInteger xwmRunningContextsCount = new AtomicInteger(0); + + private int xotsTasks = 10; + private int xotsStopDelay = 15; + + lotus.domino.NotesThread NotesLockerThread = null; + + public static XWorldsManager getInstance() { + + synchronized (XWorldsManager.class) { + if (_instance == null) { + _instance = new XWorldsManager(); + } + } + + return _instance; + } + + public boolean isStarted() { + return _started; + } + + public void Startup() { + + checkState(_started == false, "Cannot call XWorldsManager.Startup() if already running."); + checkState(Factory.isStarted() == false, "ODA Factory already started, something is wrong"); + + // Start OpenNTF Domino API Factory + + log.info("XWorlds:Manager - Starting manager"); + + // Synchronize ODA Factory initialization + synchronized (Factory.class) { + + if (!Factory.isStarted()) { + + Factory.startup(); + log.info("XWorlds:Manager - Starting XOTS"); + XotsDominoExecutor executor = new XotsDominoExecutor(xotsTasks); + try { + Xots.start(executor); + log.info("XWorlds:Manager - XOTS started"); + } catch (IllegalStateException e) { + e.printStackTrace(); + } + NotesThread.sinitThread(); + + String userIdPassword = System.getProperty("xworlds.userid.password"); + + if (userIdPassword != null) { + log.info("XWorlds:Manager - Opening UserID for this system"); + try { + // Open the id if the password is specified + NotesFactory.createSession((String) null, (String) null, userIdPassword); + } catch (NotesException e) { + e.printStackTrace(); + } + } + + log.info("XWorlds:Manager - ODA has started for: " + Factory.getLocalServerName()); + log.fine("XWorlds:Manager - Initializing nApi"); + + if (!_napiStarted) { + com.ibm.domino.napi.c.C.initLibrary(null); + _napiStarted = true; // Ensure this is started only once + } + + log.info("XWorlds:Manager - Starting system Domino thread"); + + NotesLockerThread = new NotesThread(new Runnable() { + @Override + public void run() { + boolean stopped = false; + log.info("XWorlds:Manager - Domino thread started"); + NotesThread.sinitThread(); + + while (!stopped) { + try { + Thread.sleep(4000); + } catch (InterruptedException e) { + log.info("XWorlds:Manager - Interrupted, shutting dowm system Domino thread."); + NotesThread.stermThread(); + stopped = true; + } + } + + } + }, "XWorlds System Thread"); + + NotesLockerThread.setDaemon(true); + NotesLockerThread.start(); + + NotesThread.stermThread(); + + _started = true; + + } else { + log.severe("ODA's Factory failed to start"); + } + + } + + xwmStartedCount.incrementAndGet(); + + } + + public String getXWorldsReportAsString() { + + checkState(_started == true, "XWorldsManger should bestarted to provide a report."); + + StringBuilder report = new StringBuilder(); + + report.append("Started environments count: "); + report.append(xwmStartedCount.get()); + report.append("\n"); + + report.append("Running application contexts: "); + report.append(xwmRunningContextsCount.get()); + report.append("\n"); + + report.append("Active object count: " + Factory.getActiveObjectCount() + "\n"); + report.append("Auto recycle object count: " + Factory.getAutoRecycleCount() + "\n"); + report.append("Factory counters dump:\n" + Factory.dumpCounters(true) + "\n"); + + return report.toString(); + } + + public void addApplication(String servletContextName, String contextPath, int majorVersion, int minorVersion) { + + checkNotNull(servletContextName, "The servlet context name cannot be null"); + checkNotNull(contextPath, "The servlet context path cannot be null"); + + log.info("XWorlds:Manager - Adding " + servletContextName + " [" + contextPath + "] " + majorVersion + "." + minorVersion); + + xwmRunningContextsCount.incrementAndGet(); + } + + public void removeApplication(String servletContextName, String contextPath, int majorVersion, int minorVersion) { + + checkNotNull(servletContextName, "The servlet context name cannot be null"); + checkNotNull(contextPath, "The servlet context path cannot be null"); + + log.info("XWorlds:Manager - Removing " + servletContextName + " / " + contextPath + " " + majorVersion + "." + minorVersion); + xwmRunningContextsCount.decrementAndGet(); + } + + public void Shutdown() { + + checkState(_started == true, "XWorldsManager.Shutdown() must not be called if not started"); + + if (xwmStartedCount.decrementAndGet() == 0 && _started == true) { + + // On startedCount = 0 shutdown everything + NotesLockerThread.interrupt(); + + int secs = 0; + while (NotesLockerThread.getState() != State.TERMINATED && secs < 10) { + secs++; + log.fine("Waiting for domino system thread to terminate [" + NotesLockerThread.getState() + "]"); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + } + } + + log.info("Shutting down XOTS"); + if (Xots.isStarted()) { + Xots.stop(xotsStopDelay); + } + log.info("Shutting down ODA Factory"); + if (Factory.isStarted()) { + log.fine("Shutting down ODA on thread " + Thread.currentThread().getId() + " / " + Thread.currentThread().getName()); + Factory.shutdown(); + } + + _started = false; + } + + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/XWorldsApplicationListener.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/XWorldsApplicationListener.java new file mode 100644 index 0000000..7fdfa36 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/XWorldsApplicationListener.java @@ -0,0 +1,81 @@ +package org.openntf.xworlds.appservers.webapp; + +import java.util.logging.Logger; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.openntf.domino.utils.Factory; +import org.openntf.xworlds.appservers.lifecycle.XWorldsManager; +import org.openntf.xworlds.appservers.webapp.config.DefaultXWorldsApplicationConfig; +import org.openntf.xworlds.appservers.webapp.config.XWorldsApplicationConfigurator; + +/** + * Application Lifecycle Listener implementation class XWorldsApplicationListener + * + */ +public class XWorldsApplicationListener implements ServletContextListener { + + static final java.util.logging.Logger log = Logger.getLogger(XWorldsApplicationListener.class.getName()); + + lotus.domino.NotesThread NotesController = null; + + /** + * Default constructor. + */ + public XWorldsApplicationListener() { + Factory.println("XWorlds:AppListener","Starting Application Listener"); + } + + /** + * @see ServletContextListener#contextInitialized(ServletContextEvent) + */ + public void contextInitialized(ServletContextEvent appEvent) { + + XWorldsManager xwm = XWorldsManager.getInstance(); + + // Configure XWorlds for this application + + String appConfiguratorClass = null; + XWorldsApplicationConfigurator configurator = null; + if ((appConfiguratorClass = appEvent.getServletContext().getInitParameter(XWorldsApplicationConfigurator.CONTEXTPARAM_CWAPPCONFIG_CLASS)) != null) { + try { + configurator = (XWorldsApplicationConfigurator) Class.forName(appConfiguratorClass).newInstance(); + } catch (IllegalAccessException e) { + throw new IllegalStateException("Cannot configure the XWorlds application", e); + } catch (InstantiationException e) { + throw new IllegalStateException("Cannot configure the XWorlds application", e); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("Cannot configure the XWorlds application", e); + } + } else { + configurator = new DefaultXWorldsApplicationConfig(); + } + + configurator.configure(appEvent.getServletContext()); + configurator.build(); + + xwm.addApplication(appEvent.getServletContext().getServletContextName(), + appEvent.getServletContext().getContextPath(), + appEvent.getServletContext().getMajorVersion(), + appEvent.getServletContext().getMinorVersion() + ); + + } + + /** + * @see ServletContextListener#contextDestroyed(ServletContextEvent) + */ + public void contextDestroyed(ServletContextEvent appEvent) { + + XWorldsManager xwm = XWorldsManager.getInstance(); + + xwm.removeApplication(appEvent.getServletContext().getServletContextName(), + appEvent.getServletContext().getContextPath(), + appEvent.getServletContext().getMajorVersion(), + appEvent.getServletContext().getMinorVersion() + ); + + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/XWorldsRequestsFilter.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/XWorldsRequestsFilter.java new file mode 100644 index 0000000..8605f34 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/XWorldsRequestsFilter.java @@ -0,0 +1,64 @@ +package org.openntf.xworlds.appservers.webapp; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.openntf.xworlds.appservers.lifecycle.XWorldsManagedThread; +import org.openntf.xworlds.appservers.webapp.config.XWorldsApplicationConfigurator; + +/** + * Servlet Filter implementation class XWorldsRequestsFilter + */ + +public class XWorldsRequestsFilter implements Filter { + +// static final XLogger log = XLoggerFactory.getXLogger(XWorldsRequestsFilter.class); + + /** + * Default constructor. + */ + public XWorldsRequestsFilter() { + } + + /** + * @see Filter#destroy() + */ + public void destroy() { + } + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + try { + + XWorldsManagedThread.setupAsDominoThread((HttpServletRequest) request); + XWorldsApplicationConfigurator configurator = (XWorldsApplicationConfigurator) request.getServletContext().getAttribute(XWorldsApplicationConfigurator.APPCONTEXT_ATTRS_CWAPPCONFIG); + if (configurator != null) { + configurator.setupRequest((HttpServletRequest)request, (HttpServletResponse)response); + } + + chain.doFilter(request, response); + + } finally { + XWorldsManagedThread.shutdownDominoThread(); + } + + } + + /** + * @see Filter#init(FilterConfig) + */ + public void init(FilterConfig fConfig) throws ServletException { + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/BaseXWorldsApplicationConfigurator.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/BaseXWorldsApplicationConfigurator.java new file mode 100644 index 0000000..84e01cb --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/BaseXWorldsApplicationConfigurator.java @@ -0,0 +1,31 @@ +package org.openntf.xworlds.appservers.webapp.config; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public abstract class BaseXWorldsApplicationConfigurator implements XWorldsApplicationConfigurator { + + private static final String ERROR_DONT_USE_DIRECTLY = "This base application configurator shouldn't be used directly, verify the configuration."; + private ServletContext appContext = null; + + @Override + public void configure(ServletContext context) { + throw new IllegalStateException(ERROR_DONT_USE_DIRECTLY); + + } + + @Override + public void setupRequest(HttpServletRequest request, HttpServletResponse response) { + throw new IllegalStateException(ERROR_DONT_USE_DIRECTLY); + } + + public ServletContext getAppContext() { + return appContext; + } + + public void setAppContext(ServletContext appContext) { + this.appContext = appContext; + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/DefaultXWorldsApplicationConfig.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/DefaultXWorldsApplicationConfig.java new file mode 100644 index 0000000..f20a0d8 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/DefaultXWorldsApplicationConfig.java @@ -0,0 +1,202 @@ +package org.openntf.xworlds.appservers.webapp.config; + +import java.util.logging.Logger; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import lotus.domino.NotesException; + +import org.openntf.domino.Session; +import org.openntf.domino.session.INamedSessionFactory; +import org.openntf.domino.session.ISessionFactory; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +import com.google.common.annotations.Beta; +import com.ibm.domino.napi.NException; +import com.ibm.domino.napi.c.NotesUtil; +import com.ibm.domino.napi.c.xsp.XSPNative; +import com.ibm.websphere.security.WSSecurityHelper; + + +/** + * The default configuration for a CrossWorlds Application is to use as CURRENT the following defaults: + * + *
    + *
  1. If the appserver security is enabled -> CURRENT is a named session for the request subject (caller)
  2. + *
  3. If the appserver security is disabled -> CURRENT is a native session with the identity of the USERID that's loaded
  4. + *
+ * + * @author Daniele Vistalli + * + */ +@Beta +public class DefaultXWorldsApplicationConfig extends BaseXWorldsApplicationConfigurator implements XWorldsApplicationConfiguration { + + private static final Logger log = Logger.getLogger(DefaultXWorldsApplicationConfig.class.getName()); + + private boolean _isWASSecurityEnabled = false; + private boolean _isDeveloperMode = false; + private String _defaultDevelopmentUserName = null; + private String _appSignerFullName = null; + + private static ThreadLocal dominoFullName = new ThreadLocal() { + + @Override + protected String initialValue() { + return "Anonymous"; + } + + }; + + enum IdentityLocator { + SIGNER, + CURRENT + } + + @SuppressWarnings("serial") + private class XSPBasedNamedSessionFactory implements ISessionFactory, INamedSessionFactory { + + private boolean _isFullAccess = false; + private IdentityLocator _identityLocator = null; + + public XSPBasedNamedSessionFactory(boolean fullAccess, IdentityLocator locator) { + this._isFullAccess = fullAccess; + this._identityLocator = locator; + } + + @Override + public Session createSession() { + + String username = null; + switch (_identityLocator) { + case SIGNER: + username = getAppSignerFullName(); + break; + case CURRENT: + username = getDominoFullName(); + } + + return createSession(username); + + } + + @Override + public Session createSession(String username) { + System.out.println("Username: " + username); + try { + + final long userHandle = NotesUtil.createUserNameList(username); + lotus.domino.Session rawSession = XSPNative.createXPageSessionExt(username, userHandle, false, true, _isFullAccess); + Session sess = Factory.fromLotus(rawSession, Session.SCHEMA, null); + sess.setNoRecycle(false); + return sess; + } catch (NException e) { + throw new RuntimeException(e); + } catch (NotesException e) { + throw new RuntimeException(e); + } } + }; + + private ISessionFactory namedSignerSessionFactory = new XSPBasedNamedSessionFactory(false,IdentityLocator.SIGNER); + private ISessionFactory namedSignerSessionFactoryFullAccess = new XSPBasedNamedSessionFactory(true,IdentityLocator.SIGNER); + + private ISessionFactory currentUserSessionFactory = new XSPBasedNamedSessionFactory(false,IdentityLocator.CURRENT); + private ISessionFactory currentUserSessionFactoryFullAccess = new XSPBasedNamedSessionFactory(true,IdentityLocator.CURRENT); + + + @Override + public String getAppSignerFullName() { + return _appSignerFullName; + } + + @Override + public boolean isDeveloperMode() { + return _isDeveloperMode; + } + + public void configure(ServletContext context) { + + // Save the current application context + this.setAppContext(context); + // Get from the server the current security mode + this._isWASSecurityEnabled = WSSecurityHelper.isServerSecurityEnabled(); + + // Read the signer identity + this._appSignerFullName = context.getInitParameter(CONTEXTPARAM_CWAPPSIGNER_IDENTITY); + + + // TODO Enable developermode discovery and log it + // TODO add Notes.ini developer mode configuration + if ("true".equals(System.getProperty("xworlds.developermode"))) { + this._isDeveloperMode = true; + log.warning("CrossWorlds development mode is enabled trough system property \"xworlds.developermode=true\""); + + // Read the development time identity + this._defaultDevelopmentUserName = context.getInitParameter(CONTEXTPARAM_CWDEFAULTDEVELOPER_IDENTITY); + if (_defaultDevelopmentUserName == null) { + _defaultDevelopmentUserName = "Anonymous"; + } + } + + } + + @Override + public void setupRequest(HttpServletRequest request, HttpServletResponse response) { + + // Set the session factories for the "CURRENT" session. +// if (_isWASSecurityEnabled || isDeveloperMode()) { +// // If security is enabled ("server" mode) generate named sessions based on the logged in user. +// Factory.setSessionFactory(currentUserSessionFactory, SessionType.CURRENT); +// Factory.setSessionFactory(currentUserSessionFactoryFullAccess, SessionType.CURRENT_FULL_ACCESS); +// } else { +// // If security not enabled NATIVE session is "Current ID" +// Factory.setSessionFactory(Factory.getSessionFactory(SessionType.NATIVE), SessionType.CURRENT); +// Factory.setSessionFactory(Factory.getSessionFactory(SessionType.NATIVE), SessionType.CURRENT_FULL_ACCESS); +// } + Factory.setSessionFactory(currentUserSessionFactory, SessionType.CURRENT); + Factory.setSessionFactory(currentUserSessionFactoryFullAccess, SessionType.CURRENT_FULL_ACCESS); + + // The behaviour for asSigner session is the same with security enabled or not. + if (getAppSignerFullName() != null) { + Factory.setSessionFactory(namedSignerSessionFactory, SessionType.SIGNER); + Factory.setSessionFactory(namedSignerSessionFactoryFullAccess, SessionType.SIGNER_FULL_ACCESS); + } else { + Factory.setSessionFactory(Factory.getSessionFactory(SessionType.NATIVE), SessionType.SIGNER); + Factory.setSessionFactory(Factory.getSessionFactory(SessionType.NATIVE), SessionType.SIGNER_FULL_ACCESS); + } + + if (isDeveloperMode() && request.getSession(false) != null && request.getSession(false).getAttribute("xworlds.request.username") != null) { + setDominoFullName((String) request.getSession(false).getAttribute("xworlds.request.username")); + } else if (request.getSession(false) != null && request.getSession(false).getAttribute("xworlds.request.username") != null) { + // TODO - Need to specify a different behaviour for developer mode and production to provide better security and avoid bad developer behaviour + setDominoFullName((String) request.getSession(false).getAttribute("xworlds.request.username")); + } else if (isDeveloperMode()) { + // If developer mode is enabled and no other override applies we fallback to the default development user name + setDominoFullName(_defaultDevelopmentUserName); + } + + } + + @Override + public XWorldsApplicationConfiguration build() { + getAppContext().setAttribute(APPCONTEXT_ATTRS_CWAPPCONFIG, this); + return this; + } + + public static String getDominoFullName() { + return dominoFullName.get(); + } + + public static void setDominoFullName(String newDominoFullName) { + dominoFullName.set(newDominoFullName); + } + + @Override + public String getDefaultDevelopmentUserName() { + return _defaultDevelopmentUserName; + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/XWorldsApplicationConfiguration.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/XWorldsApplicationConfiguration.java new file mode 100644 index 0000000..4881c9f --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/XWorldsApplicationConfiguration.java @@ -0,0 +1,36 @@ +package org.openntf.xworlds.appservers.webapp.config; + +public interface XWorldsApplicationConfiguration { + + /** + * @return the Notes full name for the user that will be treated as the signer for this application. + * May return null to indicate no signer has been specified. In that case the server/client identity + * is used. + */ + public String getAppSignerFullName(); + + /** + * CrossWorlds can run in developer mode allowing identity switching to simplify development & testing + * on a client based setup. + * + * Developer mode is controlled by adding + * + * CROSSWORLDSDEV=true + * + * to Notes.ini + * + * or by adding + * + * xworlds.developermode=true + * + * to bootstrap.properties + * + * Notes.ini value takes precedence over bootstrap.ini setting. + * + * @return true if CrossWorlds is running in developer mode. + */ + public boolean isDeveloperMode(); + + public String getDefaultDevelopmentUserName(); + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/XWorldsApplicationConfigurator.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/XWorldsApplicationConfigurator.java new file mode 100644 index 0000000..963d3ec --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/config/XWorldsApplicationConfigurator.java @@ -0,0 +1,45 @@ +package org.openntf.xworlds.appservers.webapp.config; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.google.common.annotations.Beta; + +@Beta +public interface XWorldsApplicationConfigurator { + + /** + * This constant is the name of the ServletContext attribute holding the application configuration. + */ + public static final String CONTEXTPARAM_CWAPPCONFIG_CLASS = "org.openntf.crossoworlds.appconfigurator.class"; + /** + * The notes full name for the identity to be used when a "SIGNER" session is required. + */ + public static final String CONTEXTPARAM_CWAPPSIGNER_IDENTITY = "org.openntf.crossworlds.appsignername"; + /** + * The notes full name for the identity to be used when a "SIGNER" session is required. + */ + public static final String CONTEXTPARAM_CWDEFAULTDEVELOPER_IDENTITY = "org.openntf.crossworlds.devtimename"; + /** + * This constant is the name of the ServletContext attribute holding the application configuration. + */ + public static final String APPCONTEXT_ATTRS_CWAPPCONFIG = "org.openntf.crossoworlds.appconfig"; + + /** + * @param context + */ + public void configure(ServletContext context); + + /** + * + */ + public XWorldsApplicationConfiguration build(); + + /** + * @param request + * @param response + */ + public void setupRequest(HttpServletRequest request, HttpServletResponse response); + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/security/SecurityManager.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/security/SecurityManager.java new file mode 100644 index 0000000..c9122d2 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/security/SecurityManager.java @@ -0,0 +1,29 @@ +package org.openntf.xworlds.appservers.webapp.security; + +import javax.servlet.http.HttpServletRequest; + +import org.openntf.xworlds.appservers.webapp.config.DefaultXWorldsApplicationConfig; + +public class SecurityManager { + + public static final String ANON_FULLNAME = "Anonymous"; + + public static void setDominoFullName(HttpServletRequest request, String fullName) { + + if (fullName == null || fullName.equals(ANON_FULLNAME)) { + request.getSession().removeAttribute("xworlds.request.username"); + DefaultXWorldsApplicationConfig.setDominoFullName(ANON_FULLNAME); + } else { + request.getSession().setAttribute("xworlds.request.username", fullName); + DefaultXWorldsApplicationConfig.setDominoFullName(fullName); + } + + } + + public static String getDominoFullName(HttpServletRequest request) { + if (request.getSession(false) != null && request.getSession(false).getAttribute("xworlds.request.username") != null) { + return (String) request.getSession().getAttribute("xworlds.request.username"); + } + return ANON_FULLNAME; + } +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/utils/XWorldsFactory.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/utils/XWorldsFactory.java new file mode 100644 index 0000000..e9b391c --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/appservers/webapp/utils/XWorldsFactory.java @@ -0,0 +1,39 @@ +package org.openntf.xworlds.appservers.webapp.utils; + +import org.openntf.domino.Session; + +import com.google.common.annotations.Beta; + +@Beta +public class XWorldsFactory { + + /** + * Call this to get a session for the user currently executing in the thread. + * + * - If the user is Anonymous you get an anonymous session + * - If the user is Authenticated by WebSphere security stack you get a session + * for the loggedin user for it's security name + * - If the current thread is not running under a "user" security context but is + * a "system" thread then a SessionType.NATIVE session is returned. + * + * @return a Domino session with the identity of the current executing user for the thread. + */ + public static Session getCallerSession() { + + return null; + } + + /** + * @return + */ + public static Session getDefaultSession() { + + return null; + } + + public static String getCallerFullName() { + + return null; + } + +} diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/core/Activator.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/core/Activator.java new file mode 100644 index 0000000..aa10399 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/core/Activator.java @@ -0,0 +1,28 @@ +package org.openntf.xworlds.core; + +import org.openntf.domino.utils.Factory; +import org.openntf.xworlds.appservers.lifecycle.XWorldsManager; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + public void start(BundleContext context) throws Exception { + Factory.println("XWorlds", "XWorlds Server bundle starting v. " + context.getBundle().getVersion()); + + Command xworldsAdminCmd = new Command(); + xworldsAdminCmd.setContext(context); + + context.registerService("java.lang.Object", xworldsAdminCmd, Command.PROPERTIES); + + XWorldsManager.getInstance().Startup(); + + } + + public void stop(BundleContext context) throws Exception { + Factory.println("XWorlds", "XWorlds Server bundle stopping"); + + XWorldsManager.getInstance().Shutdown(); + + } +} \ No newline at end of file diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/core/Command.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/core/Command.java new file mode 100644 index 0000000..3ec6e71 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/core/Command.java @@ -0,0 +1,54 @@ +package org.openntf.xworlds.core; + +import java.util.Dictionary; +import java.util.Hashtable; + +import org.openntf.domino.utils.Factory; +import org.openntf.xworlds.appservers.lifecycle.XWorldsManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleException; + +public class Command { + + static final Dictionary PROPERTIES = new Hashtable(); + + static { + // define the command scope as "jndi:" + PROPERTIES.put("osgi.command.scope", "xworlds"); + // define the command names (which map to methods) + PROPERTIES.put("osgi.command.function", "report counters install".split(" ")); + } + + private BundleContext context; + + public void report() { + System.out.println("Reporting about the status of the XWorlds Server"); + System.out.println(); + + XWorldsManager xwm = XWorldsManager.getInstance(); + + System.out.println(xwm.getXWorldsReportAsString()); + + } + + public void counters(boolean enable, boolean perThread) { + System.out.println("Setting ODA countes"); + System.out.println("Enabled: " + enable); + System.out.println("Count per thread: " + perThread); + Factory.enableCounters(enable, perThread); + } + + public void install(String packageToInstall) { + System.out.println("Installing: " + packageToInstall); + try { + context.installBundle(packageToInstall); + } catch (BundleException e) { + e.printStackTrace(); + } + } + + public void setContext(BundleContext context) { + this.context = context; + } + +} \ No newline at end of file diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/xots/XotsDominoExecutor.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/xots/XotsDominoExecutor.java new file mode 100644 index 0000000..f9ad605 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/xots/XotsDominoExecutor.java @@ -0,0 +1,92 @@ +package org.openntf.xworlds.xots; + +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.ServletException; + +import org.openntf.domino.thread.DominoExecutor; +import org.openntf.domino.thread.IWrappedCallable; +import org.openntf.domino.thread.IWrappedRunnable; + +public class XotsDominoExecutor extends DominoExecutor { + private static final Logger log_ = Logger.getLogger(XotsDominoExecutor.class.getName()); + + /** + * + * @author Paul Withers + * + */ + public static class XotsWrappedCallable extends XotsWrappedTask implements IWrappedCallable { + + public XotsWrappedCallable(final Callable wrappedObject) { + setWrappedTask(wrappedObject); + } + + @SuppressWarnings("unchecked") + @Override + public V call() throws Exception { + return (V) callOrRun(); + } + } + + /** + * + * @author Paul Withers + * + */ + public static class XotsWrappedRunnable extends XotsWrappedTask implements IWrappedRunnable { + + public XotsWrappedRunnable(final Runnable wrappedObject) { + setWrappedTask(wrappedObject); + } + + @Override + public void run() { + try { + callOrRun(); + } catch (Exception e) { + log_.log(Level.SEVERE, "Could not execute " + "/" + getWrappedTask().getClass(), e); + } + } + } + + public XotsDominoExecutor(final int corePoolSize) { + super(corePoolSize, "Xots"); + } + + /** + * Helper for WrappedCallable/WrappedRunnable + * + * @param ctx + * @param mcl + * @param wrapper + * @throws ServletException + */ + + @Override + protected IWrappedCallable wrap(final Callable inner) { + if (inner instanceof IWrappedCallable) + return (IWrappedCallable) inner; + + if (inner instanceof XotsWrappedCallable) { + return new XotsWrappedCallable(inner); + } + + return new XotsWrappedCallable(inner); + } + + @Override + protected IWrappedRunnable wrap(final Runnable inner) { + if (inner instanceof IWrappedRunnable) + return (IWrappedRunnable) inner; + + if (inner instanceof XotsWrappedRunnable) { + return new XotsWrappedRunnable(inner); + } + + return new XotsWrappedRunnable(inner); + } + +} \ No newline at end of file diff --git a/org.openntf.xworlds.core/src/org/openntf/xworlds/xots/XotsWrappedTask.java b/org.openntf.xworlds.core/src/org/openntf/xworlds/xots/XotsWrappedTask.java new file mode 100644 index 0000000..81ad983 --- /dev/null +++ b/org.openntf.xworlds.core/src/org/openntf/xworlds/xots/XotsWrappedTask.java @@ -0,0 +1,220 @@ +package org.openntf.xworlds.xots; + +import java.util.concurrent.Callable; + +import org.openntf.domino.Session; +import org.openntf.domino.session.INamedSessionFactory; +import org.openntf.domino.session.ISessionFactory; +import org.openntf.domino.thread.AbstractWrappedTask; +import org.openntf.domino.utils.DominoUtils; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; +import org.openntf.domino.xots.Tasklet; +import org.openntf.xworlds.appservers.lifecycle.XWorldsManagedThread; + +import com.ibm.domino.napi.NException; +import com.ibm.domino.napi.c.NotesUtil; +import com.ibm.domino.napi.c.xsp.XSPNative; + +import lotus.domino.NotesException; +import lotus.domino.NotesThread; + +public class XotsWrappedTask extends AbstractWrappedTask { + private Object wrappedTask; + private String dominoFullName; + private SessionType sessType; + + private class XotsNamedSessionFactory implements ISessionFactory, INamedSessionFactory { + private static final long serialVersionUID = 1L; + private boolean _isFullAccess = false; + private String _dominoFullName; + + public XotsNamedSessionFactory(boolean fullAccess, String dominoFullName) { + this._isFullAccess = fullAccess; + this._dominoFullName = dominoFullName; + } + + @Override + public Session createSession() { + + return createSession(_dominoFullName); + + } + + @Override + public Session createSession(String username) { + try { + + final long userHandle = NotesUtil.createUserNameList(username); + lotus.domino.Session rawSession = XSPNative.createXPageSessionExt(username, userHandle, false, true, _isFullAccess); + Session sess = Factory.fromLotus(rawSession, Session.SCHEMA, null); + sess.setNoRecycle(false); + return sess; + } catch (NException e) { + throw new RuntimeException(e); + } catch (NotesException e) { + throw new RuntimeException(e); + } + } + }; + + /** + * Common code for the wrappers + * + * @param module + * @param bubbleException + * @param sessionFactory + * @param callable + * @param runnable + * @return + */ + protected Object callOrRun() throws Exception { + + try { + XWorldsManagedThread.setupAsDominoThread(null); + try { + Object wrappedTask = getWrappedTask(); + + Factory.setSessionFactory(new XotsNamedSessionFactory(false, dominoFullName), sessType); + sessionFactory = Factory.getSessionFactory(SessionType.CURRENT); + + if (wrappedTask instanceof Callable) { + return ((Callable) wrappedTask).call(); + } else { + ((Runnable) wrappedTask).run(); + return null; + } + } catch (Exception e) { + DominoUtils.handleException(e); + return null; + } + } finally { + XWorldsManagedThread.shutdownDominoThread(); + } + } + + /** + * Returns the wrapped task + * + * @return + */ + protected synchronized Object getWrappedTask() { + return wrappedTask; + } + + /** + * Determines the sessionType under which the current runnable should run. + * The first non-null value of the following list is returned + *
    + *
  • If the runnable implements IDominoRunnable: result of + * getSessionType
  • + *
  • the value of {@link SessionType} Annotation
  • + *
  • DominoSessionType.DEFAULT
  • + *
+ * + * @param task + * the runnable to determine the DominoSessionType + */ + protected synchronized void setWrappedTask(final Object task) { + wrappedTask = task; + if (task == null) + return; + // some security checks... + if (task instanceof NotesThread) { + // RPr: I'm not sure if this should be allowed anyway... + throw new IllegalArgumentException("Cannot wrap the NotesThread " + task.getClass().getName() + " into a DominoRunner"); + } + // if (task instanceof DominoFutureTask) { + // // RPr: don't know if this is possible + // throw new IllegalArgumentException("Cannot wrap the WrappedCallable " + // + task.getClass().getName() + " into a DominoRunner"); + // } + if (task instanceof AbstractWrappedTask) { + // RPr: don't know if this is possible + throw new IllegalArgumentException("Cannot wrap the WrappedCallable " + task.getClass().getName() + " into a DominoRunner"); + } + + if (task instanceof Tasklet.Interface) { + Tasklet.Interface dominoRunnable = (Tasklet.Interface) task; + sessionFactory = dominoRunnable.getSessionFactory(); + scope = dominoRunnable.getScope(); + context = dominoRunnable.getContext(); + sourceThreadConfig = dominoRunnable.getThreadConfig(); + } + Tasklet annot = task.getClass().getAnnotation(Tasklet.class); + + if (annot != null) { + if (sessionFactory == null) { + switch (annot.session()) { + case CLONE: + sessType = SessionType.CURRENT; + dominoFullName = Factory.getSession(SessionType.CURRENT).getEffectiveUserName(); + break; + case CLONE_FULL_ACCESS: + sessType = SessionType.CURRENT_FULL_ACCESS; + dominoFullName = Factory.getSession(SessionType.CURRENT).getEffectiveUserName(); + break; + + case FULL_ACCESS: + sessType = SessionType.FULL_ACCESS; + dominoFullName = Factory.getSession(SessionType.SIGNER).getEffectiveUserName(); + break; + + case NATIVE: + sessType = SessionType.NATIVE; + dominoFullName = Factory.getSession(SessionType.NATIVE).getEffectiveUserName(); + break; + + case NONE: + sessionFactory = null; + break; + + case SIGNER: + sessType = SessionType.SIGNER; + dominoFullName = Factory.getSession(SessionType.SIGNER).getEffectiveUserName(); + break; + + case SIGNER_FULL_ACCESS: + sessType = SessionType.SIGNER_FULL_ACCESS; + dominoFullName = Factory.getSession(SessionType.SIGNER).getEffectiveUserName(); + break; + + case TRUSTED: + throw new IllegalStateException("SessionType.TRUSTED is not supported"); + + default: + break; + } + } + + if (context == null) { + context = annot.context(); + } + if (context == null) { + context = Tasklet.Context.DEFAULT; + } + + if (scope == null) { + scope = annot.scope(); + } + if (scope == null) { + scope = Tasklet.Scope.NONE; + } + if (sourceThreadConfig == null) { + switch (annot.threadConfig()) { + case CLONE: + sourceThreadConfig = Factory.getThreadConfig(); + break; + case PERMISSIVE: + sourceThreadConfig = Factory.PERMISSIVE_THREAD_CONFIG; + break; + case STRICT: + sourceThreadConfig = Factory.STRICT_THREAD_CONFIG; + break; + } + } + } + if (sourceThreadConfig == null) + sourceThreadConfig = Factory.getThreadConfig(); + } +} \ No newline at end of file diff --git a/org.openntf.xworlds.core/src/rebel.xml b/org.openntf.xworlds.core/src/rebel.xml new file mode 100644 index 0000000..b99c3ea --- /dev/null +++ b/org.openntf.xworlds.core/src/rebel.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.openntf.xworlds.dominodeps/.classpath b/org.openntf.xworlds.dominodeps/.classpath new file mode 100644 index 0000000..90cdb74 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.classpath @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/org.openntf.xworlds.dominodeps/.gitignore b/org.openntf.xworlds.dominodeps/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/org.openntf.xworlds.dominodeps/.project b/org.openntf.xworlds.dominodeps/.project new file mode 100644 index 0000000..0dab267 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.project @@ -0,0 +1,30 @@ + + + org.openntf.xworlds.dominodeps + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + + diff --git a/org.openntf.xworlds.dominodeps/.settings/com.ibm.etools.aries.core.prefs b/org.openntf.xworlds.dominodeps/.settings/com.ibm.etools.aries.core.prefs new file mode 100644 index 0000000..7dd2046 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/com.ibm.etools.aries.core.prefs @@ -0,0 +1,4 @@ +com.ibm.etools.aries.all=applied +com.ibm.etools.aries.java.jars=applied +com.ibm.etools.aries.web.export=applied +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.dominodeps/.settings/com.ibm.etools.webtools.packagepreferences.prefs b/org.openntf.xworlds.dominodeps/.settings/com.ibm.etools.webtools.packagepreferences.prefs new file mode 100644 index 0000000..60f37f5 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/com.ibm.etools.webtools.packagepreferences.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +use-project-settings=false diff --git a/org.openntf.xworlds.dominodeps/.settings/com.ibm.ws.st.prefs b/org.openntf.xworlds.dominodeps/.settings/com.ibm.ws.st.prefs new file mode 100644 index 0000000..b43eeb9 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/com.ibm.ws.st.prefs @@ -0,0 +1,4 @@ +com.ibm.ws.st.feature.blueprint-1.0=never +com.ibm.ws.st.feature.jndi-1.0=never +com.ibm.ws.st.feature.servlet-3.0=never +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.jdt.core.prefs b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..5ce4518 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,13 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs new file mode 100644 index 0000000..7c8126d --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs @@ -0,0 +1,5 @@ +XDOCLETBUILDERACTIVE=true +XDOCLETHOME= +XDOCLETUSEGLOBAL=true +XDOCLETVERSION=1.2.1 +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.ltk.core.refactoring.prefs b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..b196c64 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.m2e.core.prefs b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.pde.core.prefs b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..9e852b9 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,6 @@ +BUNDLE_ROOT_PATH=BundleContent +eclipse.preferences.version=1 +manifest.exportWizard=com.ibm.etools.aries.bundle.export +manifest.launchShortcuts=org.eclipse.wst.server.launchShortcut,org.eclipse.wst.server.launchShortcut +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.wst.common.component b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..840a854 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.wst.common.component @@ -0,0 +1,6 @@ + + + + + + diff --git a/org.openntf.xworlds.dominodeps/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..5289bad --- /dev/null +++ b/org.openntf.xworlds.dominodeps/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.openntf.xworlds.dominodeps/BundleContent/META-INF/MANIFEST.MF b/org.openntf.xworlds.dominodeps/BundleContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000..dd1224d --- /dev/null +++ b/org.openntf.xworlds.dominodeps/BundleContent/META-INF/MANIFEST.MF @@ -0,0 +1,193 @@ +Manifest-Version: 1.0 +Bnd-LastModified: 1422718817653 +Build-Jdk: 1.7.0_15 +Built-By: Daniele Vistalli +Bundle-Creator: Factor-y S.r.l. +Bundle-Vendor: OpenNTF Org +Bundle-ClassPath: com.ibm.icu_3.8.1.v20120530.jar, + com.ibm.icu.base_3.8.1.v20080530.jar, + lwpd.commons.jar, + lwpd.domino.napi.jar, + Notes.jar, + META-INF/ +Import-Package: com.ibm.commons, + com.ibm.commons.extension, + com.ibm.commons.log, + com.ibm.commons.log.eclipse, + com.ibm.commons.log.jdk, + com.ibm.commons.platform, + com.ibm.commons.preferences, + com.ibm.commons.preferences.eclipse, + com.ibm.commons.util, + com.ibm.commons.util.io, + com.ibm.commons.util.io.base64, + com.ibm.commons.util.io.json, + com.ibm.commons.util.io.json.parser, + com.ibm.commons.util.io.json.util, + com.ibm.commons.util.print, + com.ibm.commons.util.profiler, + com.ibm.designer.domino.napi, + com.ibm.designer.domino.napi.design, + com.ibm.designer.domino.napi.dxl, + com.ibm.designer.domino.napi.struct, + com.ibm.designer.domino.napi.util, + com.ibm.domino.napi, + com.ibm.domino.napi.c, + com.ibm.domino.napi.c.callback, + com.ibm.domino.napi.c.data, + com.ibm.domino.napi.c.html, + com.ibm.domino.napi.c.ref, + com.ibm.domino.napi.c.ssl, + com.ibm.domino.napi.c.struct, + com.ibm.domino.napi.c.util, + com.ibm.domino.napi.c.xsp, + com.ibm.domino.napi.internal.c, + com.ibm.domino.napi.ssl, + com.ibm.domino.napi.util, + com.ibm.icu.impl, + com.ibm.icu.impl.data, + com.ibm.icu.impl.duration, + com.ibm.icu.impl.duration.impl, + com.ibm.icu.lang, + com.ibm.icu.math, + com.ibm.icu.text, + com.ibm.icu.util, + com.ibm.sslight, + com.ibm.sslight.tools, + lotus.domino, + lotus.domino.corba, + lotus.domino.corba.NameAndObjectUPackage, + lotus.domino.cso, + lotus.domino.local, + lotus.domino.util, + org.omg.CORBA +Export-Package: com.ibm.commons, + com.ibm.commons.log, + com.ibm.commons.log.jdk, + com.ibm.commons.platform, + com.ibm.commons.preferences, + com.ibm.commons.preferences.eclipse, + com.ibm.commons.util, + com.ibm.commons.util.io, + com.ibm.commons.util.io.base64, + com.ibm.commons.util.io.json, + com.ibm.commons.util.io.json.parser, + com.ibm.commons.util.io.json.util, + com.ibm.commons.util.print, + com.ibm.commons.util.profiler, + com.ibm.designer.domino.napi, + com.ibm.designer.domino.napi.design, + com.ibm.designer.domino.napi.dxl, + com.ibm.designer.domino.napi.struct, + com.ibm.designer.domino.napi.util, + com.ibm.domino.napi, + com.ibm.domino.napi.c, + com.ibm.domino.napi.c.callback, + com.ibm.domino.napi.c.data, + com.ibm.domino.napi.c.html, + com.ibm.domino.napi.c.ref, + com.ibm.domino.napi.c.ssl, + com.ibm.domino.napi.c.struct, + com.ibm.domino.napi.c.util, + com.ibm.domino.napi.c.xsp, + com.ibm.domino.napi.internal.c, + com.ibm.domino.napi.ssl, + com.ibm.domino.napi.util, + com.ibm.icu.impl, + com.ibm.icu.impl.data, + com.ibm.icu.impl.duration, + com.ibm.icu.impl.duration.impl, + com.ibm.icu.lang, + com.ibm.icu.math, + com.ibm.icu.text, + com.ibm.icu.util, + com.ibm.sslight, + com.ibm.sslight.tools, + lotus.domino, + lotus.domino.corba, + lotus.domino.corba.NameAndObjectUPackage, + lotus.domino.cso, + lotus.domino.local, + lotus.domino.util +Provide-Package: Acme, + Acme.JPM.Encoders, + com.ibm.commons, + com.ibm.commons.extension, + com.ibm.commons.log, + com.ibm.commons.log.eclipse, + com.ibm.commons.log.jdk, + com.ibm.commons.platform, + com.ibm.commons.preferences, + com.ibm.commons.preferences.eclipse, + com.ibm.commons.util, + com.ibm.commons.util.io, + com.ibm.commons.util.io.base64, + com.ibm.commons.util.io.json, + com.ibm.commons.util.io.json.parser, + com.ibm.commons.util.io.json.util, + com.ibm.commons.util.print, + com.ibm.commons.util.profiler, + com.ibm.designer.domino.napi, + com.ibm.designer.domino.napi.design, + com.ibm.designer.domino.napi.dxl, + com.ibm.designer.domino.napi.struct, + com.ibm.designer.domino.napi.util, + com.ibm.domino.napi, + com.ibm.domino.napi.c, + com.ibm.domino.napi.c.callback, + com.ibm.domino.napi.c.data, + com.ibm.domino.napi.c.html, + com.ibm.domino.napi.c.ref, + com.ibm.domino.napi.c.ssl, + com.ibm.domino.napi.c.struct, + com.ibm.domino.napi.c.util, + com.ibm.domino.napi.c.xsp, + com.ibm.domino.napi.internal.c, + com.ibm.domino.napi.ssl, + com.ibm.domino.napi.util, + com.ibm.icu.impl, + com.ibm.icu.impl.data, + com.ibm.icu.impl.duration, + com.ibm.icu.impl.duration.impl, + com.ibm.icu.lang, + com.ibm.icu.math, + com.ibm.icu.text, + com.ibm.icu.util, + com.ibm.sslight, + com.ibm.sslight.tools, + lotus.domino, + lotus.domino.corba, + lotus.domino.corba.NameAndObjectUPackage, + lotus.domino.cso, + lotus.domino.local, + lotus.domino.util, + lotus.notes, + lotus.notes.addins, + lotus.notes.addins.changeman, + lotus.notes.addins.changeman.control, + lotus.notes.addins.changeman.functions, + lotus.notes.addins.changeman.monitor, + lotus.notes.addins.changeman.roboadmin, + lotus.notes.addins.changeman.workflow, + lotus.notes.addins.daytime, + lotus.notes.addins.dsfclassifier, + lotus.notes.addins.dsflearning, + lotus.notes.addins.guru, + lotus.notes.addins.ispy, + lotus.notes.addins.ispy.net, + lotus.notes.addins.ispy.net.dns, + lotus.notes.addins.ispy.net.portcheck, + lotus.notes.addins.ispy.util, + lotus.notes.addins.rmeval, + lotus.notes.addins.util, + lotus.notes.apps.reports, + lotus.notes.apps.wmsgtrc, + lotus.notes.internal, + lotus.priv.CORBA.iiop, + lotus.priv.CORBA.iiop.ssl, + lotus.priv.CORBA.iiop.sslight, + lotus.priv.CORBA.java.Exception, + lotus.priv.CORBA.portable +Bundle-SymbolicName: org.openntf.xworlds.dominodeps +Bundle-Version: 9.0.1 +Bundle-Name: org.openntf.xworlds.dominodeps diff --git a/org.openntf.xworlds.dominodeps/BundleContent/build.properties b/org.openntf.xworlds.dominodeps/BundleContent/build.properties new file mode 100644 index 0000000..dd31cc8 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/BundleContent/build.properties @@ -0,0 +1,7 @@ +bin.includes = Notes.jar,\ + lwpd.domino.napi.jar,\ + com.ibm.icu_3.8.1.v20120530.jar,\ + com.ibm.icu.base_3.8.1.v20080530.jar,\ + lwpd.commons.jar,\ + META-INF/ + \ No newline at end of file diff --git a/org.openntf.xworlds.dominodeps/dependencies.txt b/org.openntf.xworlds.dominodeps/dependencies.txt new file mode 100644 index 0000000..fa73e87 --- /dev/null +++ b/org.openntf.xworlds.dominodeps/dependencies.txt @@ -0,0 +1,7 @@ +CrossWorlds runtiem dependencies + +Notes.jar -> com.ibm.notes.java.api_9.0.1.20140404-1000.jar +lwpd.domino.napi.jar -> com.ibm.domino.napi_9.0.1.20140404-1000.jar +com.ibm.icu.base_3.8.1.v20080530.jar -> com.ibm.icu.base_3.8.1.v20080530.jar +com.ibm.icu_3.8.1.v20120530.jar -> com.ibm.icu_3.8.1.v20120530.jar +lwpd.commons.jar -> com.ibm.commons_9.0.1.20140404-1000.jar \ No newline at end of file diff --git a/org.openntf.xworlds.features.server/.project b/org.openntf.xworlds.features.server/.project new file mode 100644 index 0000000..0c5d929 --- /dev/null +++ b/org.openntf.xworlds.features.server/.project @@ -0,0 +1,23 @@ + + + org.openntf.xworlds.features.server + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.common.modulecore.ModuleCoreNature + + diff --git a/org.openntf.xworlds.features.server/.settings/com.ibm.etools.webtools.packagepreferences.prefs b/org.openntf.xworlds.features.server/.settings/com.ibm.etools.webtools.packagepreferences.prefs new file mode 100644 index 0000000..60f37f5 --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/com.ibm.etools.webtools.packagepreferences.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +use-project-settings=false diff --git a/org.openntf.xworlds.features.server/.settings/com.ibm.ws.st.osgi.internal.feature.runtime.xml b/org.openntf.xworlds.features.server/.settings/com.ibm.ws.st.osgi.internal.feature.runtime.xml new file mode 100644 index 0000000..8fdd7f5 --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/com.ibm.ws.st.osgi.internal.feature.runtime.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/org.openntf.xworlds.features.server/.settings/com.ibm.ws.st.prefs b/org.openntf.xworlds.features.server/.settings/com.ibm.ws.st.prefs new file mode 100644 index 0000000..56d8a5d --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/com.ibm.ws.st.prefs @@ -0,0 +1,2 @@ +com.ibm.ws.st.feature.blueprint-1.0=always +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.features.server/.settings/org.eclipse.core.resources.prefs b/org.openntf.xworlds.features.server/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..79f82c8 --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding//OSGI-INF/SUBSYSTEM.MF=UTF-8 diff --git a/org.openntf.xworlds.features.server/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/org.openntf.xworlds.features.server/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs new file mode 100644 index 0000000..7c8126d --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs @@ -0,0 +1,5 @@ +XDOCLETBUILDERACTIVE=true +XDOCLETHOME= +XDOCLETUSEGLOBAL=true +XDOCLETVERSION=1.2.1 +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.features.server/.settings/org.eclipse.ltk.core.refactoring.prefs b/org.openntf.xworlds.features.server/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..b196c64 --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.common.component b/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..2677d81 --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.common.component @@ -0,0 +1,5 @@ + + + + + diff --git a/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..68fdcf2 --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.xsl.core.prefs b/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.xsl.core.prefs new file mode 100644 index 0000000..e28962c --- /dev/null +++ b/org.openntf.xworlds.features.server/.settings/org.eclipse.wst.xsl.core.prefs @@ -0,0 +1,11 @@ +CHECK_CALL_TEMPLATES=2 +CHECK_XPATHS=2 +CIRCULAR_REF=2 +DUPLICATE_PARAMETER=2 +EMPTY_PARAM=1 +MISSING_INCLUDE=2 +MISSING_PARAM=1 +NAME_ATTRIBUTE_EMPTY=2 +NAME_ATTRIBUTE_MISSING=2 +TEMPLATE_CONFLICT=2 +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.features.server/OSGI-INF/SUBSYSTEM.MF b/org.openntf.xworlds.features.server/OSGI-INF/SUBSYSTEM.MF new file mode 100644 index 0000000..112629d --- /dev/null +++ b/org.openntf.xworlds.features.server/OSGI-INF/SUBSYSTEM.MF @@ -0,0 +1,285 @@ +Manifest-Version: 1.0 +Subsystem-ManifestVersion: 1.0 +IBM-Feature-Version: 2 +IBM-ShortName: CrossWorlds-1.0 +Subsystem-Localization: OSGI-INF/l10n/xworlds +Subsystem-SymbolicName: org.openntf.xworlds.server;visibility:=public +Subsystem-Name: %name +Subsystem-Description: %desc +Subsystem-Version: 0.0.1.qualifier +Subsystem-Type: osgi.subsystem.feature +Subsystem-Content: org.openntf.xworlds.dominodeps;version=9.0.1, + org.openntf.xworlds.core;version=1.0.0, + org.openntf.xworlds.oda;version=2.0.1 +Subsystem-License: http://www.apache.org/licenses/LICENSE-2.0.html +IBM-App-ForceRestart: install,uninstall +IBM-API-Package: com.google.common.annotations, + com.google.common.base, + com.google.common.base.internal, + com.google.common.cache, + com.google.common.collect, + com.google.common.escape, + com.google.common.eventbus, + com.google.common.hash, + com.google.common.html, + com.google.common.io, + com.google.common.math, + com.google.common.net, + com.google.common.primitives, + com.google.common.reflect, + com.google.common.util.concurrent, + com.google.common.xml, + com.google.thirdparty.publicsuffix, + com.ibm.commons, + com.ibm.commons.extension, + com.ibm.commons.icu, + com.ibm.commons.log, + com.ibm.commons.log.eclipse, + com.ibm.commons.log.jdk, + com.ibm.commons.platform, + com.ibm.commons.preferences, + com.ibm.commons.preferences.eclipse, + com.ibm.commons.util, + com.ibm.commons.util.io, + com.ibm.commons.util.io.base64, + com.ibm.commons.util.io.json, + com.ibm.commons.util.io.json.parser, + com.ibm.commons.util.io.json.util, + com.ibm.commons.util.print, + com.ibm.commons.util.profiler, + com.ibm.designer.domino.napi, + com.ibm.designer.domino.napi.design, + com.ibm.designer.domino.napi.dxl, + com.ibm.designer.domino.napi.struct, + com.ibm.designer.domino.napi.util, + com.ibm.domino.napi, + com.ibm.domino.napi.c, + com.ibm.domino.napi.c.callback, + com.ibm.domino.napi.c.data, + com.ibm.domino.napi.c.html, + com.ibm.domino.napi.c.ref, + com.ibm.domino.napi.c.ssl, + com.ibm.domino.napi.c.struct, + com.ibm.domino.napi.c.util, + com.ibm.domino.napi.c.xsp, + com.ibm.domino.napi.internal.c, + com.ibm.domino.napi.ssl, + com.ibm.domino.napi.util, + com.ibm.icu.impl, + com.ibm.icu.impl.data, + com.ibm.icu.impl.data.icudt38b, + com.ibm.icu.impl.data.icudt38b.brkitr, + com.ibm.icu.impl.data.icudt38b.coll, + com.ibm.icu.impl.data.icudt38b.rbnf, + com.ibm.icu.impl.data.icudt38b.translit, + com.ibm.icu.impl.duration, + com.ibm.icu.impl.duration.impl, + com.ibm.icu.lang, + com.ibm.icu.lang;version=3.8.1, + com.ibm.icu.math, + com.ibm.icu.math;version=3.8.1, + com.ibm.icu.text, + com.ibm.icu.text;version=3.8.1, + com.ibm.icu.util, + com.ibm.icu.util;version=3.8.1, + com.ibm.sslight, + com.ibm.sslight.tools, + com.tinkerpop.blueprints, + com.tinkerpop.blueprints.oupls.jung, + com.tinkerpop.blueprints.util, + com.tinkerpop.blueprints.util.io, + com.tinkerpop.blueprints.util.wrappers, + com.tinkerpop.blueprints.util.wrappers.event, + com.tinkerpop.blueprints.util.wrappers.event.listener, + com.tinkerpop.blueprints.util.wrappers.id, + com.tinkerpop.blueprints.util.wrappers.partition, + com.tinkerpop.blueprints.util.wrappers.readonly, + com.tinkerpop.blueprints.util.wrappers.wrapped, + com.tinkerpop.frames, + com.tinkerpop.frames.annotations, + com.tinkerpop.frames.annotations.gremlin, + com.tinkerpop.frames.core, + com.tinkerpop.frames.modules, + com.tinkerpop.frames.modules.javahandler, + com.tinkerpop.frames.modules.typedgraph, + com.tinkerpop.frames.structures, + com.tinkerpop.frames.util, + com.tinkerpop.gremlin, + com.tinkerpop.gremlin.java, + com.tinkerpop.pipes, + com.tinkerpop.pipes.branch, + com.tinkerpop.pipes.filter, + com.tinkerpop.pipes.sideeffect, + com.tinkerpop.pipes.transform, + com.tinkerpop.pipes.util, + com.tinkerpop.pipes.util.iterators, + com.tinkerpop.pipes.util.structures, + javassist, + javassist.bytecode, + javassist.bytecode.analysis, + javassist.bytecode.annotation, + javassist.bytecode.stackmap, + javassist.compiler, + javassist.compiler.ast, + javassist.convert, + javassist.expr, + javassist.runtime, + javassist.scopedpool, + javassist.tools, + javassist.tools.reflect, + javassist.tools.rmi, + javassist.tools.web, + javassist.util, + javassist.util.proxy, + javax.annotation, + javax.annotation.concurrent, + javax.annotation.meta, + javax.realtime, + javolution, + javolution.context, + javolution.context.internal, + javolution.io, + javolution.lang, + javolution.osgi.internal, + javolution.text, + javolution.text.internal, + javolution.tools, + javolution.util, + javolution.util.function, + javolution.util.internal, + javolution.util.internal.bitset, + javolution.util.internal.collection, + javolution.util.internal.comparator, + javolution.util.internal.map, + javolution.util.internal.map.sorted, + javolution.util.internal.set, + javolution.util.internal.set.sorted, + javolution.util.internal.table, + javolution.util.internal.table.sorted, + javolution.util.service, + javolution.xml, + javolution.xml.internal, + javolution.xml.internal.stream, + javolution.xml.sax, + javolution.xml.stream, + javolution.xml.ws, + lotus.domino, + lotus.domino.corba, + lotus.domino.corba.NameAndObjectUPackage, + lotus.domino.cso, + lotus.domino.local, + lotus.domino.util, + lotus.notes, + lotus.notes.addins, + lotus.notes.addins.changeman, + lotus.notes.addins.changeman.control, + lotus.notes.addins.changeman.functions, + lotus.notes.addins.changeman.monitor, + lotus.notes.addins.changeman.roboadmin, + lotus.notes.addins.changeman.workflow, + lotus.notes.addins.daytime, + lotus.notes.addins.dsfclassifier, + lotus.notes.addins.dsflearning, + lotus.notes.addins.guru, + lotus.notes.addins.ispy, + lotus.notes.addins.ispy.net, + lotus.notes.addins.ispy.net.dns, + lotus.notes.addins.ispy.net.portcheck, + lotus.notes.addins.ispy.util, + lotus.notes.addins.rmeval, + lotus.notes.addins.util, + lotus.notes.apps.reports, + lotus.notes.apps.wmsgtrc, + lotus.notes.internal, + lotus.priv.CORBA.iiop, + lotus.priv.CORBA.iiop.ssl, + lotus.priv.CORBA.iiop.sslight, + lotus.priv.CORBA.java.Exception, + lotus.priv.CORBA.portable, + org.hamcrest, + org.hamcrest.core, + org.hamcrest.internal, + org.openntf.arpa, + org.openntf.calendars, + org.openntf.domino, + org.openntf.domino.annotations, + org.openntf.domino.big, + org.openntf.domino.big.impl, + org.openntf.domino.design, + org.openntf.domino.design.cd, + org.openntf.domino.design.impl, + org.openntf.domino.email, + org.openntf.domino.events, + org.openntf.domino.exceptions, + org.openntf.domino.ext, + org.openntf.domino.formula, + org.openntf.domino.graph, + org.openntf.domino.graph2, + org.openntf.domino.graph2.annotations, + org.openntf.domino.graph2.builtin, + org.openntf.domino.graph2.builtin.social, + org.openntf.domino.graph2.builtin.workflow, + org.openntf.domino.graph2.builtin.workflow.definition, + org.openntf.domino.graph2.exception, + org.openntf.domino.graph2.impl, + org.openntf.domino.helpers, + org.openntf.domino.i18n, + org.openntf.domino.impl, + org.openntf.domino.iterators, + org.openntf.domino.junit, + org.openntf.domino.logging, + org.openntf.domino.nsfdata, + org.openntf.domino.nsfdata.impldxl, + org.openntf.domino.nsfdata.impldxl.item, + org.openntf.domino.nsfdata.structs, + org.openntf.domino.nsfdata.structs.cd, + org.openntf.domino.schema, + org.openntf.domino.schema.exceptions, + org.openntf.domino.schema.impl, + org.openntf.domino.schema.types, + org.openntf.domino.session, + org.openntf.domino.tests, + org.openntf.domino.tests.eknori, + org.openntf.domino.tests.jpg, + org.openntf.domino.tests.ntf, + org.openntf.domino.tests.paul, + org.openntf.domino.tests.rpr, + org.openntf.domino.tests.rpr.formula, + org.openntf.domino.tests.xmage, + org.openntf.domino.thread, + org.openntf.domino.transactions, + org.openntf.domino.types, + org.openntf.domino.utils, + org.openntf.domino.utils.xml, + org.openntf.domino.xots, + org.openntf.domino.xots.events, + org.openntf.domino.xsp, + org.openntf.domino.xsp.adapter, + org.openntf.domino.xsp.components, + org.openntf.domino.xsp.config, + org.openntf.domino.xsp.formula, + org.openntf.domino.xsp.helpers, + org.openntf.domino.xsp.junit, + org.openntf.domino.xsp.junit.test, + org.openntf.domino.xsp.model, + org.openntf.domino.xsp.msg, + org.openntf.domino.xsp.readers, + org.openntf.domino.xsp.script, + org.openntf.domino.xsp.session, + org.openntf.domino.xsp.xots, + org.openntf.formula, + org.openntf.formula.annotation, + org.openntf.formula.ast, + org.openntf.formula.function, + org.openntf.formula.impl, + org.openntf.formula.parse, + org.openntf.formula.test, + org.openntf.service, + org.openntf.xworlds.appservers.lifecycle, + org.openntf.xworlds.appservers.webapp, + org.openntf.xworlds.appservers.webapp.config, + org.openntf.xworlds.appservers.webapp.utils, + org.openntf.xworlds.core, + org.openntf.xworlds.appservers.webapp.security, + org.openntf.xworlds.xots + diff --git a/org.openntf.xworlds.features.server/OSGI-INF/l10n/xworlds.properties b/org.openntf.xworlds.features.server/OSGI-INF/l10n/xworlds.properties new file mode 100644 index 0000000..2538a92 --- /dev/null +++ b/org.openntf.xworlds.features.server/OSGI-INF/l10n/xworlds.properties @@ -0,0 +1,2 @@ +name=OpenNTF-CrossWorlds +desc=CrossWorlds is the server that mixes IBM WebSphere Liberty and IBM Domino. This features enables running a domino server "inProcess". Thanks to the native API and ODA API performance is pushed to the limit. \ No newline at end of file diff --git a/org.openntf.xworlds.oda/.classpath b/org.openntf.xworlds.oda/.classpath new file mode 100644 index 0000000..3ec2b50 --- /dev/null +++ b/org.openntf.xworlds.oda/.classpath @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/org.openntf.xworlds.oda/.project b/org.openntf.xworlds.oda/.project new file mode 100644 index 0000000..4ddc852 --- /dev/null +++ b/org.openntf.xworlds.oda/.project @@ -0,0 +1,40 @@ + + + org.openntf.xworlds.oda + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.pde.PluginNature + + diff --git a/org.openntf.xworlds.oda/.settings/com.ibm.etools.aries.core.prefs b/org.openntf.xworlds.oda/.settings/com.ibm.etools.aries.core.prefs new file mode 100644 index 0000000..7dd2046 --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/com.ibm.etools.aries.core.prefs @@ -0,0 +1,4 @@ +com.ibm.etools.aries.all=applied +com.ibm.etools.aries.java.jars=applied +com.ibm.etools.aries.web.export=applied +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.oda/.settings/com.ibm.etools.webtools.packagepreferences.prefs b/org.openntf.xworlds.oda/.settings/com.ibm.etools.webtools.packagepreferences.prefs new file mode 100644 index 0000000..60f37f5 --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/com.ibm.etools.webtools.packagepreferences.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +use-project-settings=false diff --git a/org.openntf.xworlds.oda/.settings/org.eclipse.jdt.core.prefs b/org.openntf.xworlds.oda/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..c537b63 --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/org.openntf.xworlds.oda/.settings/org.eclipse.pde.core.prefs b/org.openntf.xworlds.oda/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..9e852b9 --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,6 @@ +BUNDLE_ROOT_PATH=BundleContent +eclipse.preferences.version=1 +manifest.exportWizard=com.ibm.etools.aries.bundle.export +manifest.launchShortcuts=org.eclipse.wst.server.launchShortcut,org.eclipse.wst.server.launchShortcut +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/org.openntf.xworlds.oda/.settings/org.eclipse.wst.common.component b/org.openntf.xworlds.oda/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..fa2f959 --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/org.eclipse.wst.common.component @@ -0,0 +1,6 @@ + + + + + + diff --git a/org.openntf.xworlds.oda/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.openntf.xworlds.oda/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..60f6640 --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.openntf.xworlds.oda/.settings/org.eclipse.wst.validation.prefs b/org.openntf.xworlds.oda/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..981829a --- /dev/null +++ b/org.openntf.xworlds.oda/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,9 @@ +DELEGATES_PREFERENCE=delegateValidatorList +USER_BUILD_PREFERENCE=enabledBuildValidatorListcom.ibm.jee.sdo.jdbc.ui.validators.JDBCMediatorConnectionFileValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListcom.ibm.jee.sdo.jdbc.ui.validators.JDBCMediatorConnectionFileValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator; +USER_PREFERENCE=overrideGlobalPreferencestruedisableAllValidationfalseversion1.2.501.v201304022101 +eclipse.preferences.version=1 +override=true +suspend=false +vals/org.eclipse.wst.html.core.HTMLValidator/global=FF01 +vf.version=3 diff --git a/org.openntf.xworlds.oda/BundleContent/META-INF/MANIFEST.MF b/org.openntf.xworlds.oda/BundleContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000..90b066b --- /dev/null +++ b/org.openntf.xworlds.oda/BundleContent/META-INF/MANIFEST.MF @@ -0,0 +1,290 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: org.openntf.xworlds.oda +Bundle-SymbolicName: org.openntf.xworlds.oda +Bundle-Version: 2.0.1.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ClassPath: com.google.guava_18.0.0.jar, + com.tinkerpop_2.6.0.jar, + javassist_3.18.2.jar, + javolution_6.1.0.jar, + jsr305_1.0.0.jar, + org.openntf.domino_2.0.1.jar, + org.openntf.domino.xsp_2.0.1.jar, + org.openntf.formula_2.0.1.jar, + org.openntf.junit4xpages_4.11.0.jar +Export-Package: com.google.common.annotations, + com.google.common.base, + com.google.common.base.internal, + com.google.common.cache, + com.google.common.collect, + com.google.common.escape, + com.google.common.eventbus, + com.google.common.hash, + com.google.common.html, + com.google.common.io, + com.google.common.math, + com.google.common.net, + com.google.common.primitives, + com.google.common.reflect, + com.google.common.util.concurrent, + com.google.common.xml, + com.google.thirdparty.publicsuffix, + com.tinkerpop.blueprints, + com.tinkerpop.blueprints.util, + com.tinkerpop.blueprints.util.io, + com.tinkerpop.blueprints.util.wrappers, + com.tinkerpop.blueprints.util.wrappers.event, + com.tinkerpop.blueprints.util.wrappers.event.listener, + com.tinkerpop.blueprints.util.wrappers.id, + com.tinkerpop.blueprints.util.wrappers.partition, + com.tinkerpop.blueprints.util.wrappers.readonly, + com.tinkerpop.blueprints.util.wrappers.wrapped, + com.tinkerpop.frames, + com.tinkerpop.frames.annotations, + com.tinkerpop.frames.annotations.gremlin, + com.tinkerpop.frames.core, + com.tinkerpop.frames.modules, + com.tinkerpop.frames.modules.javahandler, + com.tinkerpop.frames.modules.typedgraph, + com.tinkerpop.frames.structures, + com.tinkerpop.frames.util, + com.tinkerpop.gremlin, + com.tinkerpop.gremlin.java, + com.tinkerpop.pipes, + com.tinkerpop.pipes.branch, + com.tinkerpop.pipes.filter, + com.tinkerpop.pipes.sideeffect, + com.tinkerpop.pipes.transform, + com.tinkerpop.pipes.util, + com.tinkerpop.pipes.util.iterators, + com.tinkerpop.pipes.util.structures, + javassist, + javassist.bytecode, + javassist.bytecode.analysis, + javassist.bytecode.annotation, + javassist.bytecode.stackmap, + javassist.compiler, + javassist.compiler.ast, + javassist.convert, + javassist.expr, + javassist.runtime, + javassist.scopedpool, + javassist.tools, + javassist.tools.reflect, + javassist.tools.rmi, + javassist.tools.web, + javassist.util.proxy, + javax.annotation, + javax.annotation.concurrent, + javax.annotation.meta, + javax.realtime, + javolution.context, + javolution.context.internal, + javolution.io, + javolution.lang, + javolution.osgi.internal, + javolution.text, + javolution.text.internal, + javolution.tools, + javolution.util, + javolution.util.function, + javolution.util.internal, + javolution.util.internal.bitset, + javolution.util.internal.collection, + javolution.util.internal.comparator, + javolution.util.internal.map, + javolution.util.internal.map.sorted, + javolution.util.internal.set, + javolution.util.internal.set.sorted, + javolution.util.internal.table, + javolution.util.internal.table.sorted, + javolution.util.service, + javolution.xml, + javolution.xml.internal, + javolution.xml.internal.stream, + javolution.xml.sax, + javolution.xml.stream, + javolution.xml.ws, + junit.extensions, + junit.framework, + junit.runner, + junit.textui, + org.eclipse.jdt.internal.junit.runner, + org.eclipse.jdt.internal.junit.runner.junit3, + org.eclipse.jdt.internal.junit4.runner, + org.hamcrest, + org.hamcrest.core, + org.hamcrest.internal, + org.junit, + org.junit.experimental, + org.junit.experimental.categories, + org.junit.experimental.max, + org.junit.experimental.results, + org.junit.experimental.runners, + org.junit.experimental.theories, + org.junit.experimental.theories.internal, + org.junit.experimental.theories.suppliers, + org.junit.internal, + org.junit.internal.builders, + org.junit.internal.matchers, + org.junit.internal.requests, + org.junit.internal.runners, + org.junit.internal.runners.model, + org.junit.internal.runners.rules, + org.junit.internal.runners.statements, + org.junit.matchers, + org.junit.rules, + org.junit.runner, + org.junit.runner.manipulation, + org.junit.runner.notification, + org.junit.runners, + org.junit.runners.model, + org.openntf.arpa, + org.openntf.calendars, + org.openntf.domino, + org.openntf.domino.annotations, + org.openntf.domino.big, + org.openntf.domino.big.impl, + org.openntf.domino.design, + org.openntf.domino.design.impl, + org.openntf.domino.email, + org.openntf.domino.events, + org.openntf.domino.exceptions, + org.openntf.domino.ext, + org.openntf.domino.formula, + org.openntf.domino.graph, + org.openntf.domino.graph2, + org.openntf.domino.graph2.annotations, + org.openntf.domino.graph2.builtin, + org.openntf.domino.graph2.builtin.social, + org.openntf.domino.graph2.builtin.workflow, + org.openntf.domino.graph2.builtin.workflow.definition, + org.openntf.domino.graph2.exception, + org.openntf.domino.graph2.impl, + org.openntf.domino.helpers, + org.openntf.domino.i18n, + org.openntf.domino.impl, + org.openntf.domino.iterators, + org.openntf.domino.junit, + org.openntf.domino.logging, + org.openntf.domino.nsfdata, + org.openntf.domino.nsfdata.impldxl, + org.openntf.domino.nsfdata.impldxl.item, + org.openntf.domino.nsfdata.structs, + org.openntf.domino.nsfdata.structs.cd, + org.openntf.domino.schema, + org.openntf.domino.schema.exceptions, + org.openntf.domino.schema.impl, + org.openntf.domino.schema.types, + org.openntf.domino.session, + org.openntf.domino.tests, + org.openntf.domino.tests.eknori, + org.openntf.domino.tests.jpg, + org.openntf.domino.tests.ntf, + org.openntf.domino.tests.paul, + org.openntf.domino.tests.rpr, + org.openntf.domino.tests.rpr.formula, + org.openntf.domino.tests.xmage, + org.openntf.domino.thread, + org.openntf.domino.transactions, + org.openntf.domino.types, + org.openntf.domino.utils, + org.openntf.domino.utils.xml, + org.openntf.domino.xots, + org.openntf.domino.xots.events, + org.openntf.domino.xsp, + org.openntf.domino.xsp.adapter, + org.openntf.domino.xsp.components, + org.openntf.domino.xsp.config, + org.openntf.domino.xsp.formula, + org.openntf.domino.xsp.helpers, + org.openntf.domino.xsp.junit, + org.openntf.domino.xsp.junit.test, + org.openntf.domino.xsp.model, + org.openntf.domino.xsp.msg, + org.openntf.domino.xsp.readers, + org.openntf.domino.xsp.script, + org.openntf.domino.xsp.session, + org.openntf.domino.xsp.xots, + org.openntf.formula, + org.openntf.formula.annotation, + org.openntf.formula.ast, + org.openntf.formula.function, + org.openntf.formula.impl, + org.openntf.formula.parse, + org.openntf.formula.test, + org.openntf.junit4xpages, + org.openntf.service +Import-Package: Acme, + Acme.JPM.Encoders, + com.ibm.commons, + com.ibm.commons.extension, + com.ibm.commons.log, + com.ibm.commons.log.eclipse, + com.ibm.commons.log.jdk, + com.ibm.commons.platform, + com.ibm.commons.preferences, + com.ibm.commons.preferences.eclipse, + com.ibm.commons.util, + com.ibm.commons.util.io, + com.ibm.commons.util.io.base64, + com.ibm.commons.util.io.json, + com.ibm.commons.util.io.json.parser, + com.ibm.commons.util.io.json.util, + com.ibm.commons.util.print, + com.ibm.commons.util.profiler, + com.ibm.domino.napi, + com.ibm.domino.napi.c, + com.ibm.domino.napi.c.callback, + com.ibm.domino.napi.c.data, + com.ibm.domino.napi.c.html, + com.ibm.domino.napi.c.ref, + com.ibm.domino.napi.c.ssl, + com.ibm.domino.napi.c.struct, + com.ibm.domino.napi.c.util, + com.ibm.domino.napi.c.xsp, + com.ibm.domino.napi.internal.c, + com.ibm.domino.napi.ssl, + com.ibm.domino.napi.util, + com.ibm.icu.impl, + com.ibm.icu.impl.data, + com.ibm.icu.impl.duration, + com.ibm.icu.impl.duration.impl, + com.ibm.icu.lang, + com.ibm.icu.math, + com.ibm.icu.text, + com.ibm.icu.util, + lotus.domino, + lotus.domino.corba, + lotus.domino.corba.NameAndObjectUPackage, + lotus.domino.cso, + lotus.domino.local, + lotus.domino.util, + lotus.notes, + lotus.notes.addins, + lotus.notes.addins.changeman, + lotus.notes.addins.changeman.control, + lotus.notes.addins.changeman.functions, + lotus.notes.addins.changeman.monitor, + lotus.notes.addins.changeman.roboadmin, + lotus.notes.addins.changeman.workflow, + lotus.notes.addins.daytime, + lotus.notes.addins.dsfclassifier, + lotus.notes.addins.dsflearning, + lotus.notes.addins.guru, + lotus.notes.addins.ispy, + lotus.notes.addins.ispy.net, + lotus.notes.addins.ispy.net.dns, + lotus.notes.addins.ispy.net.portcheck, + lotus.notes.addins.ispy.util, + lotus.notes.addins.rmeval, + lotus.notes.addins.util, + lotus.notes.apps.reports, + lotus.notes.apps.wmsgtrc, + lotus.notes.internal, + lotus.priv.CORBA.iiop, + lotus.priv.CORBA.iiop.ssl, + lotus.priv.CORBA.iiop.sslight, + lotus.priv.CORBA.java.Exception, + lotus.priv.CORBA.portable diff --git a/org.openntf.xworlds.oda/BundleContent/build.properties b/org.openntf.xworlds.oda/BundleContent/build.properties new file mode 100644 index 0000000..c05dc7a --- /dev/null +++ b/org.openntf.xworlds.oda/BundleContent/build.properties @@ -0,0 +1,9 @@ +bin.includes = com.google.guava_18.0.0.jar,\ + com.tinkerpop_2.6.0.jar,\ + javassist_3.18.2.jar,\ + javolution_6.1.0.jar,\ + jsr305_1.0.0.jar,\ + org.openntf.domino.xsp_2.0.1.jar,\ + org.openntf.domino_2.0.1.jar,\ + org.openntf.formula_2.0.1.jar,\ + org.openntf.junit4xpages_4.11.0.jar diff --git a/org.openntf.xworlds.oda/build.properties b/org.openntf.xworlds.oda/build.properties new file mode 100644 index 0000000..940e622 --- /dev/null +++ b/org.openntf.xworlds.oda/build.properties @@ -0,0 +1,13 @@ +# Ant properties for building the ODA package +# +# To keep the source tree clean you should copy this file to build-local.properties and +# set properties in it. +# +# build-local.properties needs to be ignored in your git/svn configuration +# + +# The path to the "built" update site for ODA on your machine +oda.updatesitedir=C:/Temp/oda + +# The build qualifier for the JARs from ODA. It will be stripped when copying to XWorlds ODA +oda.buildver=201511101308 \ No newline at end of file diff --git a/org.openntf.xworlds.oda/build.xml b/org.openntf.xworlds.oda/build.xml new file mode 100644 index 0000000..edeea34 --- /dev/null +++ b/org.openntf.xworlds.oda/build.xml @@ -0,0 +1,32 @@ + + + + + ODA Dependencies for CrossWorlds + + + + + + + + + + + + + + + + + + + + diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.classpath b/org.openntf.xworlds.webapp.j2eeenabler/.classpath new file mode 100644 index 0000000..b2936d1 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.classpath @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.gitignore b/org.openntf.xworlds.webapp.j2eeenabler/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.project b/org.openntf.xworlds.webapp.j2eeenabler/.project new file mode 100644 index 0000000..0544c0c --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.project @@ -0,0 +1,36 @@ + + + org.openntf.xworlds.webapp.j2eeenabler + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + + diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.settings/com.ibm.ws.st.prefs b/org.openntf.xworlds.webapp.j2eeenabler/.settings/com.ibm.ws.st.prefs new file mode 100644 index 0000000..96dcc9b --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.settings/com.ibm.ws.st.prefs @@ -0,0 +1,2 @@ +com.ibm.ws.st.feature.servlet-3.0=never +eclipse.preferences.version=1 diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.jdt.core.prefs b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..69c31cd --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.m2e.core.prefs b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.wst.common.component b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..862e703 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.wst.common.component @@ -0,0 +1,5 @@ + + + + + diff --git a/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.wst.common.project.facet.core.xml b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..739d5fb --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.openntf.xworlds.webapp.j2eeenabler/README.md b/org.openntf.xworlds.webapp.j2eeenabler/README.md new file mode 100644 index 0000000..dc116d1 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/README.md @@ -0,0 +1,15 @@ +# j2eeenabler for CrossWorlds applications + +This JAR project is a Servlet 3.0 WebFragment that should be added to any application needing CrossWorlds +services. + +This jar add to the web application + +1) An ApplicationListener which controls initialization / registration / deregistration / shutdown of services + +2) A servlet filter applying to /* which sets up/tear down Domino thread context per request + +The jar from this project needs to be copied into the WEB-INF/lib directory of you web applications. + + +It only contains the web-fragment.xml as the classed are shared in the core library at the applicaiton server level. diff --git a/org.openntf.xworlds.webapp.j2eeenabler/bin/META-INF/web-fragment.xml b/org.openntf.xworlds.webapp.j2eeenabler/bin/META-INF/web-fragment.xml new file mode 100644 index 0000000..4fc4292 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/bin/META-INF/web-fragment.xml @@ -0,0 +1,21 @@ + + +org.openntf.xworlds.webapp.j2eeenabler + org_openntf_xworlds_webapp_j2eeenabler + + XWorldsApplicationListener + org.openntf.xworlds.appservers.webapp.XWorldsApplicationListener + + + XWorldsRequestsFilter + + org.openntf.xworlds.appservers.webapp.XWorldsRequestsFilter + + true + + + XWorldsRequestsFilter + /* + REQUEST + + \ No newline at end of file diff --git a/org.openntf.xworlds.webapp.j2eeenabler/pom.xml b/org.openntf.xworlds.webapp.j2eeenabler/pom.xml new file mode 100644 index 0000000..d446050 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + org.openntf.xworlds.webapp + j2eeenabler + 0.0.1-SNAPSHOT + The web-fragment you need to add to your CrossWorlds applications. + + + com.ibm.tools.target + was-liberty + LATEST + pom + provided + + + + src + + + src + + **/*.java + + + + + + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-jar-plugin + + + + \ No newline at end of file diff --git a/org.openntf.xworlds.webapp.j2eeenabler/src/META-INF/MANIFEST.MF b/org.openntf.xworlds.webapp.j2eeenabler/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..254272e --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: + diff --git a/org.openntf.xworlds.webapp.j2eeenabler/src/META-INF/web-fragment.xml b/org.openntf.xworlds.webapp.j2eeenabler/src/META-INF/web-fragment.xml new file mode 100644 index 0000000..4fc4292 --- /dev/null +++ b/org.openntf.xworlds.webapp.j2eeenabler/src/META-INF/web-fragment.xml @@ -0,0 +1,21 @@ + + +org.openntf.xworlds.webapp.j2eeenabler + org_openntf_xworlds_webapp_j2eeenabler + + XWorldsApplicationListener + org.openntf.xworlds.appservers.webapp.XWorldsApplicationListener + + + XWorldsRequestsFilter + + org.openntf.xworlds.appservers.webapp.XWorldsRequestsFilter + + true + + + XWorldsRequestsFilter + /* + REQUEST + + \ No newline at end of file diff --git a/samples/ConferenceApp/.classpath b/samples/ConferenceApp/.classpath new file mode 100644 index 0000000..7fef084 --- /dev/null +++ b/samples/ConferenceApp/.classpath @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/ConferenceApp/.factorypath b/samples/ConferenceApp/.factorypath new file mode 100644 index 0000000..f0013fa --- /dev/null +++ b/samples/ConferenceApp/.factorypath @@ -0,0 +1,4 @@ + + + + diff --git a/samples/ConferenceApp/.gitignore b/samples/ConferenceApp/.gitignore new file mode 100644 index 0000000..9ed481c --- /dev/null +++ b/samples/ConferenceApp/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/target/ diff --git a/samples/ConferenceApp/.project b/samples/ConferenceApp/.project new file mode 100644 index 0000000..b2bc1fb --- /dev/null +++ b/samples/ConferenceApp/.project @@ -0,0 +1,56 @@ + + + ConferenceApp + + + org.openntf.xworlds.webapp.j2eeenabler + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.zeroturnaround.eclipse.rebelXmlBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.jsdt.core.jsNature + org.zeroturnaround.eclipse.jrebelNature + + + + plugins + 2 + D:/dev/gitroot/org.openntf.domino/domino/org.openntf.domino.updatesite/target/site/plugins + + + diff --git a/samples/ConferenceApp/.settings/.jsdtscope b/samples/ConferenceApp/.settings/.jsdtscope new file mode 100644 index 0000000..3a28de0 --- /dev/null +++ b/samples/ConferenceApp/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/samples/ConferenceApp/.settings/com.ibm.etools.webtools.packagepreferences.prefs b/samples/ConferenceApp/.settings/com.ibm.etools.webtools.packagepreferences.prefs new file mode 100644 index 0000000..60f37f5 --- /dev/null +++ b/samples/ConferenceApp/.settings/com.ibm.etools.webtools.packagepreferences.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +use-project-settings=false diff --git a/samples/ConferenceApp/.settings/com.vaadin.designer.prefs b/samples/ConferenceApp/.settings/com.vaadin.designer.prefs new file mode 100644 index 0000000..6499804 --- /dev/null +++ b/samples/ConferenceApp/.settings/com.vaadin.designer.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +paletteComponents={"items"\:["com.vaadin.ui.BrowserFrame","com.vaadin.ui.Button","com.vaadin.ui.CheckBox","com.vaadin.ui.ColorPicker","com.vaadin.ui.ColorPickerArea","com.vaadin.ui.ComboBox","com.vaadin.ui.Flash","com.vaadin.ui.Grid","com.vaadin.ui.Image","com.vaadin.ui.InlineDateField","com.vaadin.ui.Label","com.vaadin.ui.Link","com.vaadin.ui.ListSelect","com.vaadin.ui.MenuBar","com.vaadin.ui.NativeButton","com.vaadin.ui.NativeSelect","com.vaadin.ui.OptionGroup","com.vaadin.ui.PasswordField","com.vaadin.ui.PopupDateField","com.vaadin.ui.ProgressBar","com.vaadin.ui.RichTextArea","com.vaadin.ui.Slider","com.vaadin.ui.Table","com.vaadin.ui.TextArea","com.vaadin.ui.TextField","com.vaadin.ui.Tree","com.vaadin.ui.TreeTable","com.vaadin.ui.TwinColSelect","com.vaadin.ui.Upload"],"expanded"\:true} +paletteLayouts={"items"\:["com.vaadin.ui.AbsoluteLayout","com.vaadin.ui.Accordion","com.vaadin.ui.CssLayout","com.vaadin.ui.FormLayout","com.vaadin.ui.HorizontalLayout","com.vaadin.ui.HorizontalSplitPanel","com.vaadin.ui.Panel","com.vaadin.ui.TabSheet","com.vaadin.ui.VerticalLayout","com.vaadin.ui.VerticalSplitPanel"],"expanded"\:true} +serverAddress=192.168.74.184 +serverPort=65279 +theme=valo diff --git a/samples/ConferenceApp/.settings/com.vaadin.integration.eclipse.prefs b/samples/ConferenceApp/.settings/com.vaadin.integration.eclipse.prefs new file mode 100644 index 0000000..ccb4ae2 --- /dev/null +++ b/samples/ConferenceApp/.settings/com.vaadin.integration.eclipse.prefs @@ -0,0 +1,6 @@ +com.vaadin.integration.eclipse.useLatestNightly=false +com.vaadin.integration.eclipse.widgetsetBuildsSuspended=true +com.vaadin.integration.eclipse.widgetsetDirty=false +com.vaadin.integration.eclipse.widgetsetStyle=OBF +com.vaadin.integration.eclipse.widgetsetVerbose=true +eclipse.preferences.version=1 diff --git a/samples/ConferenceApp/.settings/org.eclipse.jdt.apt.core.prefs b/samples/ConferenceApp/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..6b471d7 --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.reconcileEnabled=true diff --git a/samples/ConferenceApp/.settings/org.eclipse.jdt.core.prefs b/samples/ConferenceApp/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..f07f891 --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.processAnnotations=enabled +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/samples/ConferenceApp/.settings/org.eclipse.m2e.core.prefs b/samples/ConferenceApp/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/samples/ConferenceApp/.settings/org.eclipse.wst.common.component b/samples/ConferenceApp/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..25b3b27 --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.wst.common.component @@ -0,0 +1,12 @@ + + + + + + + uses + + + + + diff --git a/samples/ConferenceApp/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/samples/ConferenceApp/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml new file mode 100644 index 0000000..9a9579a --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/samples/ConferenceApp/.settings/org.eclipse.wst.common.project.facet.core.xml b/samples/ConferenceApp/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..ff2221b --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/samples/ConferenceApp/.settings/org.eclipse.wst.jsdt.ui.superType.container b/samples/ConferenceApp/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/samples/ConferenceApp/.settings/org.eclipse.wst.jsdt.ui.superType.name b/samples/ConferenceApp/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/samples/ConferenceApp/.settings/org.eclipse.wst.validation.prefs b/samples/ConferenceApp/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..04cad8c --- /dev/null +++ b/samples/ConferenceApp/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,2 @@ +disabled=06target +eclipse.preferences.version=1 diff --git a/samples/ConferenceApp/BeyondSessionsApp/.bowerrc b/samples/ConferenceApp/BeyondSessionsApp/.bowerrc new file mode 100644 index 0000000..dd348af --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "client/bower_components/" +} \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/.gitignore b/samples/ConferenceApp/BeyondSessionsApp/.gitignore new file mode 100644 index 0000000..7870bdc --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/.gitignore @@ -0,0 +1,5 @@ +client/bower_components/ +._.DS_Store +Thumbs.db +node_modules/ +build/ \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/Gruntfile.js b/samples/ConferenceApp/BeyondSessionsApp/Gruntfile.js new file mode 100644 index 0000000..ad715b5 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/Gruntfile.js @@ -0,0 +1,103 @@ +module.exports = function(grunt) { + + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + banner: '/* <%= pkg.name %> <%= pkg.version %> <%= grunt.template.today("yyyy-mm-dd h:MM") %> */\n', + clean: ["build"], + copy: { + main: { + files: [ + {expand: true, src: [ + 'client/images/connected.png', + 'client/images/mark.jpg', + 'client/images/marky.jpg', + 'client/images/m-swball.gif', + 'client/images/beer.jpeg' + ], + dest: 'build/client/images', flatten : true}, + {expand: true, src : [ + 'client/bower_components/font-awesome/fonts/*', + + ], dest : 'build/client/fonts', flatten : true} + ] + } + }, + + /*create Angular JS files from the partials (html files)*/ + html2js : { + options: { + base : 'client' + }, + main: { + src: ['client/partials/*.html'], + dest: 'client/templates.js' + } + }, + + concat: { + styles: { + options: { banner: '<%= banner %>' }, + src: [ + 'client/bower_components/bootswatch/united/bootstrap.min.css', + 'client/styles.css', + 'client/bower_components/font-awesome/css/font-awesome.min.css', + 'client/bower_components/animate.css/animate.min.css' + ], + dest: 'build/client/css/styles-all.css' + }, + js: { + options: { banner: '<%= banner %>' }, + src: [ + + "client/bower_components/angular/angular.min.js", + + "client/polyfills.js", + "client/app.js", + "client/utils.js", + "client/services.js", + "client/sessions.js", + "client/templates.js", + + "client/bower_components/angular-animate/angular-animate.min.js", + "client/bower_components/angular-resource/angular-resource.min.js", + "client/bower_components/angular-ui-router/release/angular-ui-router.min.js", + "client/bower_components/angular-local-storage/dist/angular-local-storage.min.js", + + "client/bower_components/angular-bootstrap/ui-bootstrap.min.js", + "client/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js", + + "client/bower_components/fastclick/lib/fastclick.js" + + ], + dest: 'build/client/libs.js' + } + }, + + watch : { + scripts: { + files: ['**/*.js', '**/*.html'], + tasks: ['default'], + options: { + spawn: false, + } + } + } + + }); + + grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-copy'); + grunt.loadNpmTasks('grunt-contrib-clean'); + grunt.loadNpmTasks('grunt-html2js'); + grunt.loadNpmTasks('grunt-contrib-watch'); + + // Default task(s) + grunt.registerTask('default', [ + 'copy', + 'concat:styles', + 'concat:js', + 'html2js' + ]); + +}; \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/LICENSE b/samples/ConferenceApp/BeyondSessionsApp/LICENSE new file mode 100644 index 0000000..e06d208 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/samples/ConferenceApp/BeyondSessionsApp/README.md b/samples/ConferenceApp/BeyondSessionsApp/README.md new file mode 100644 index 0000000..9905f44 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/README.md @@ -0,0 +1,2 @@ +# BeyondSessionsApp +Demo app for our session at ConnectED 2015 diff --git a/samples/ConferenceApp/BeyondSessionsApp/bower.json b/samples/ConferenceApp/BeyondSessionsApp/bower.json new file mode 100644 index 0000000..af4b7a6 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/bower.json @@ -0,0 +1,30 @@ +{ + "name": "connect15-sessions-app", + "version": "0.0.0", + "authors": [ + "Mark Leusink " + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ], + "dependencies": { + "fastclick": "~1.0.3", + "bootstrap": ">=3.3", + "font-awesome": "~4.2.0", + "angular-ui-router": "~0.2.13", + "angular-animate": "~1.3.5", + "angular-resource": "~1.3.5", + "animate.css": "~3.2.0", + "angular-bootstrap": "~0.12.0", + "angular-local-storage": "~0.1.5", + "bootswatch": "~3.3.1" + }, + "resolutions": { + "angular": ">= 1.0.8" + } +} diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/app.js b/samples/ConferenceApp/BeyondSessionsApp/client/app.js new file mode 100644 index 0000000..858b35a --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/app.js @@ -0,0 +1,195 @@ +/* +TODO: +- grunt task to concat JS files / template cache (performance optimization) +- full screen: issue on iOS (needs top padding) +*/ + +/* + ngResource + ngAnimate: animations + ui.rooter: router + ui.bootstrap: dropdowns + LocalStorage: store favorites unid +*/ + +var app = angular.module("sessionsApp", [ + 'templates-main', + 'ngResource', + 'ngAnimate', + 'ui.router', + 'ui.bootstrap', + 'LocalStorageModule', + 'sessionApp.utils', + 'sessionsApp.controllers', + 'sessionsApp.services' + ]); + +app.constant('sessionsRestUrl', 'http://beyondtheeveryday.com/beyond/connect2015.nsf/api/data/'); +app.constant('favoritesRestUrl', 'http://beyondtheeveryday.com/beyond/favorites.nsf/api/data/'); + +app.config( function($stateProvider, localStorageServiceProvider) { + + /*setup the routes*/ + $stateProvider + + .state('about', { //about the app + url: '/about', + templateUrl: 'partials/about.html', + title : 'About' + }) + .state('feedback', { + url: '/feedback', + templateUrl: 'partials/feedback.html', + title : 'Feedback', + controller : 'FeedbackCtrl' + }) + .state('nowNext', { + url: '/nowNext', + templateUrl: 'partials/nownext.html', + title : 'Now & Next', + controller : 'NowNextCtrl' + }) + .state('map', { //map of the venue + url: '/map', + templateUrl: 'partials/map.html', + title : 'Swan Map' + }) + .state('sessionsAll', { //all sessions + url: '/sessionsAll', + templateUrl: 'partials/sessions.html', + controller: 'SessionsCtrl', + title : 'All sessions', + + }) + .state('sessionsByDay', { + url: '/sessionsByDay/:dayNo', + templateUrl: 'partials/sessions.html', + controller: 'SessionsByDayCtrl', + title : 'Sessions' + }) + .state('sessionsByTrack', { + url: '/sessionsByTrack/:trackId', + templateUrl: 'partials/sessions.html', + controller: 'SessionsByTrackCtrl', + title : 'Sessions' + }) + .state('favorites', { + url: '/favorites', + templateUrl: 'partials/sessions.html', + controller: 'FavoritesCtrl', + title : 'Favorites' + }) + .state('sessionDetails', { //show session details + url: '/sessions/:sessionId', + templateUrl: 'partials/session.html', + controller: 'SessionCtrl', + title : 'Session' + }); + + /*set up local storage*/ + localStorageServiceProvider + .setPrefix('bte'); + +}); + +app.controller("MainCtrl", function($rootScope, $scope, $timeout, utils, localStorageService, SessionsFactory) { + + //function to toggle/hide/show the offcanvas + $scope.toggleOffCanvas = function() { + //we add the noscroll class to the body so it can't be scrolled + //while the offcanvas is opened + angular.element( document.body).toggleClass('noscroll'); + angular.element( document.getElementById('offcanvas')).toggleClass('active'); + angular.element( document.getElementById('container')).toggleClass('active'); + }; + $scope.hideOffCanvas = function() { + angular.element( document.body).removeClass('noscroll'); + angular.element( document.getElementById('offcanvas')).removeClass('active'); + angular.element( document.getElementById('container')).removeClass('active'); + }; + + $scope.tracks = []; + + //load the tracks and get the color for every track + SessionsFactory.getTracks().then( function(tracks) { + + angular.forEach( tracks, function(track) { + + var color = utils.getColorForTrack(track.name); + track.clazz = 'bg-' + color + ( $scope.activeMenu == track.name ? ' active' : ''); + + }); + + $scope.tracks = tracks; + }); + + $scope.menuDays = [ + {id: '0', label:'Sunday'}, + {id: '1', label:'Monday'}, + {id: '2', label:'Tuesday'}, + {id: '3', label:'Wednesday'} + ]; + + //set default active menu option + $scope.pageTitle = "ConnectED 2015 Sessions"; + $scope.activeMenu = "about"; + + $rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) { + + if (fromState.name.indexOf('sessions') == 0 ) { + $rootScope.yOffset = window.pageYOffset; + } + + //store last state, but not for session details + if (toState.name != 'sessionDetails') { + localStorageService.set('lastState', toState.name, {path : '/', expires: 365} ); + } + + if (toState.name == 'sessionsByDay' ) { + $scope.pageTitle = toState.title + ': ' + utils.getFullDayName(toParams.dayNo); + $scope.activeMenu = toState.name + toParams.dayId; + } else if (toState.name == 'sessionsByTrack' ) { + $scope.pageTitle = toParams.trackId; + $scope.activeMenu = toParams.trackId; + } else { + $scope.pageTitle = toState.title; + $scope.activeMenu = toState.name; + } + + } ); + + $rootScope.$on('$stateChangeSuccess', function(e, toState, toParams, fromState, fromParams) { + + $timeout( function() { + + var yOffset = 0; + + if (toState.name.indexOf('sessions') == 0 && $rootScope.yOffset) { + yOffset = $rootScope.yOffset; + } + + window.scrollTo(0, yOffset); + + }, 0); + + + }); + + +}); + +app.run( function($state, localStorageService) { + + //enable fastclick + FastClick.attach(document.body); + + //go to last saved state or the default state) + var lastState = localStorageService.get('lastState'); + + if (lastState == null || lastState.length == 0) { + lastState = 'about'; + } + + $state.go(lastState); + +}); diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/1-simple.html b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/1-simple.html new file mode 100644 index 0000000..c7e8e94 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/1-simple.html @@ -0,0 +1,32 @@ + + + + + + Beyond 1 + + + + + + + + + + +
+ + Hi! Below the text '10' is shown - Angular style + +

+ {{ 2 + 8 }} +

+ + + +
+ + + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/2-controller.html b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/2-controller.html new file mode 100644 index 0000000..b2db6e4 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/2-controller.html @@ -0,0 +1,52 @@ + + + + + Beyond 2 + + + + + + + + + + + + + +
+ +

Hi {{user}}

+ + + + + + + + + + + + + +
+ {{session.title}} + + + + + + +
+ + + +
+ + + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/2b-search.html b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/2b-search.html new file mode 100644 index 0000000..07afa92 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/2b-search.html @@ -0,0 +1,49 @@ + + + + + Beyond 2b + + + + + + + + + + + + + + +
+ +
+ + Find a session: + +
+ + + + + + + + + +
+ {{session.title}} + + +
+ + + +
+ + + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/3-remote.html b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/3-remote.html new file mode 100644 index 0000000..273b4cd --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/3-remote.html @@ -0,0 +1,40 @@ + + + + + Beyond 3 + + + + + + + + + + + + + +
+ + + + + + + + +
+ {{session.title}} + + +
+ + +
+ + + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/4-create.html b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/4-create.html new file mode 100644 index 0000000..ef35415 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/4-create.html @@ -0,0 +1,69 @@ + + + + + Beyond 4 + + + + + + + + + + + + + +
+
+ +

{{sessions.length}} sessions found

+ + + + + + + + + +
+ {{session.title}} + + + + + + +
+ +
+ +
+
+ +
Add a session
+
+ + Title: + + + +
+ +
+
+
+ +
+ +
+ + + + + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/2-controller.js b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/2-controller.js new file mode 100644 index 0000000..f7f12c5 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/2-controller.js @@ -0,0 +1,16 @@ + +var app = angular.module('beyondApp', []); + +app.controller('SessionsCtrl', ['$scope', function($scope) { + + //$scope = access to controller from the view + + $scope.user = 'Mark'; + + $scope.sessions = [ + { 'title' : 'Domino', 'image' : 'img/grolsch.jpg'}, + { 'title' : 'Connections', 'image' : 'img/jupiler.jpg'}, + { 'title' : 'Worklight', 'image' : 'img/heineken.jpg'} + ]; + +}]); diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/3-remote.js b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/3-remote.js new file mode 100644 index 0000000..8bacb80 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/3-remote.js @@ -0,0 +1,14 @@ + +var app = angular.module('beyondApp', []); + +app.controller('SessionsCtrl', ['$scope', '$http', function($scope, $http){ + + $http.get('http://beyondtheeveryday.com/beyond/connect2015.nsf/api/data/collections/name/sessionsAll') + + .success( function(data) { + + $scope.sessions = data; + + }); + +}]); diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/4-create.js b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/4-create.js new file mode 100644 index 0000000..953dd61 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/basic-samples/js/4-create.js @@ -0,0 +1,49 @@ + +var app = angular.module('beyondApp', []); + +app.controller('SessionsCtrl', ['$scope', '$http', function($scope, $http){ + + var baseUrl = 'http://beyondtheeveryday.com/beyond/connect2015.nsf'; + + //initial call to populate the list of sessions + getAllSessions(); + + //function to create a session + $scope.createSession = function() { + $http.post( baseUrl + '/api/data/documents?form=frmSessionTest', $scope.formData) + .success(function(data) { + + $scope.formData = {}; //clear form + + //let's make another get request to populate the list with the newly added session + getAllSessions(); + + }) + .error(function(data) { + console.log('Error: ' + data); + }); + }; + + //delete a session + $scope.deleteSession = function(session) { + + $http.delete( baseUrl + '/api/data/documents/unid/' + session['@unid'] ) + .success(function(data) { + getAllSessions(); + }) + .error(function(data) { + console.log('Error: ' + data); + }); + + }; + + function getAllSessions() { + + $http.get( baseUrl + '/api/data/collections/name/sessionsAll') + .success( function(data) { + $scope.sessions = data; + }); + + } + +}]); diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/images/beer.jpeg b/samples/ConferenceApp/BeyondSessionsApp/client/images/beer.jpeg new file mode 100644 index 0000000..cb81973 Binary files /dev/null and b/samples/ConferenceApp/BeyondSessionsApp/client/images/beer.jpeg differ diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/images/connected.png b/samples/ConferenceApp/BeyondSessionsApp/client/images/connected.png new file mode 100644 index 0000000..20008db Binary files /dev/null and b/samples/ConferenceApp/BeyondSessionsApp/client/images/connected.png differ diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/images/m-swball.gif b/samples/ConferenceApp/BeyondSessionsApp/client/images/m-swball.gif new file mode 100644 index 0000000..871e7c6 Binary files /dev/null and b/samples/ConferenceApp/BeyondSessionsApp/client/images/m-swball.gif differ diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/images/mark.jpg b/samples/ConferenceApp/BeyondSessionsApp/client/images/mark.jpg new file mode 100644 index 0000000..94d93d8 Binary files /dev/null and b/samples/ConferenceApp/BeyondSessionsApp/client/images/mark.jpg differ diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/images/marky.jpg b/samples/ConferenceApp/BeyondSessionsApp/client/images/marky.jpg new file mode 100644 index 0000000..75adc31 Binary files /dev/null and b/samples/ConferenceApp/BeyondSessionsApp/client/images/marky.jpg differ diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/index.html b/samples/ConferenceApp/BeyondSessionsApp/client/index.html new file mode 100644 index 0000000..48d0756 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/index.html @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + IBM ConnectED 2015 Sessions + + + + + + + + + + + + + + + +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/partials/about.html b/samples/ConferenceApp/BeyondSessionsApp/client/partials/about.html new file mode 100644 index 0000000..c770854 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/partials/about.html @@ -0,0 +1,59 @@ +
+ +
+ +
+ +
+ +
+ +
+ +

Hi!

+

This is the demo app for our session at ConnectED 2015 in January in Orlando: "The Future of Web Development - Write Once, Run Everywhere with AngularJS and Domino". It is build using AngularJS and uses an IBM Domino backend.

+ +

In our session we're going to talk about building web apps using the AngularJS JavaScript framework, with data coming from a Domino backend using REST. We will show you how an app built like this can run in multiple runtimes, like Domino, Bluemix, Connections, Microsoft Sharepoint and MobileFirst Foundation (previously Worklight).

+ +

If you haven't registered for ConnectED yet: + register now and we'll see you on Monday at 3:45 PM at the Swan - Toucan 1-2. It'll be worth it! +

+ + + +
+ + + +

Here comes the fine print...

+ +

+ We did our best. Worked our ass off. But take absolutely no liability for the accurateness of the data in this app. Or if the app will work at all. It probably will. We hope (if it doesn't: please let us know). If you want the ConnectED session data used by this app in a comfortable Notes database, check out the Totally Unofficial Totally Unsupported IBM ConnectED Session Database by Mat Newman and others. +

+

+ Oh, and if you want to know more about how this app was built: talk to us if you see us walking around. That's what a conference is all about (you seriously thought it was the sessions?). We are not scary and will talk for beer +

+

+ This source code of this app is publicly available on GitHub. +

+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/partials/feedback.html b/samples/ConferenceApp/BeyondSessionsApp/client/partials/feedback.html new file mode 100644 index 0000000..ba84bdd --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/partials/feedback.html @@ -0,0 +1,39 @@ +
+ +
+ +
+ +

+ We love to hear what you think about this app. Got remarks? Suggestions? Please let us know! +

+ +
+ +
+ + +
+ +
+ + +
+ +
+ +
+ +
+ +
+ Got it. Thanks for that! +
+ +
+ + +
+ +
\ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/partials/map.html b/samples/ConferenceApp/BeyondSessionsApp/client/partials/map.html new file mode 100644 index 0000000..086950f --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/partials/map.html @@ -0,0 +1,13 @@ +
+ +
+ +
+ + + +
+ +
+ +
\ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/partials/nownext.html b/samples/ConferenceApp/BeyondSessionsApp/client/partials/nownext.html new file mode 100644 index 0000000..568ac0f --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/partials/nownext.html @@ -0,0 +1,42 @@ + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/partials/session.html b/samples/ConferenceApp/BeyondSessionsApp/client/partials/session.html new file mode 100644 index 0000000..96b49db --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/partials/session.html @@ -0,0 +1,45 @@ +
+ +
+ +
+ +
+

{{session.title}}

+
{{::session.startTimeDesc}} - {{::session.endTimeDesc}} in {{::session.room}} | {{::session.sessionId}}
+
+ +
+ +
+ + + + Back +
+ +
+ {{::session.description}} +
+ + + +
Speakers
+ +
+ +
+ {{speaker}} +
+ +
+ +
+ +
+ +
+ +
diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/partials/sessions.html b/samples/ConferenceApp/BeyondSessionsApp/client/partials/sessions.html new file mode 100644 index 0000000..7e6ed26 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/partials/sessions.html @@ -0,0 +1,35 @@ + \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/polyfills.js b/samples/ConferenceApp/BeyondSessionsApp/client/polyfills.js new file mode 100644 index 0000000..b402d99 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/polyfills.js @@ -0,0 +1,68 @@ + +//polyfill for indexOf function, +// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf +// Production steps of ECMA-262, Edition 5, 15.4.4.14 +// Reference: http://es5.github.io/#x15.4.4.14 +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function(searchElement, fromIndex) { + + var k; + + // 1. Let O be the result of calling ToObject passing + // the this value as the argument. + if (this == null) { + throw new TypeError('"this" is null or not defined'); + } + + var O = Object(this); + + // 2. Let lenValue be the result of calling the Get + // internal method of O with the argument "length". + // 3. Let len be ToUint32(lenValue). + var len = O.length >>> 0; + + // 4. If len is 0, return -1. + if (len === 0) { + return -1; + } + + // 5. If argument fromIndex was passed let n be + // ToInteger(fromIndex); else let n be 0. + var n = +fromIndex || 0; + + if (Math.abs(n) === Infinity) { + n = 0; + } + + // 6. If n >= len, return -1. + if (n >= len) { + return -1; + } + + // 7. If n >= 0, then Let k be n. + // 8. Else, n<0, Let k be len - abs(n). + // If k is less than 0, then let k be 0. + k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); + + // 9. Repeat, while k < len + while (k < len) { + // a. Let Pk be ToString(k). + // This is implicit for LHS operands of the in operator + // b. Let kPresent be the result of calling the + // HasProperty internal method of O with argument Pk. + // This step can be combined with c + // c. If kPresent is true, then + // i. Let elementK be the result of calling the Get + // internal method of O with the argument ToString(k). + // ii. Let same be the result of applying the + // Strict Equality Comparison Algorithm to + // searchElement and elementK. + // iii. If same is true, return k. + if (k in O && O[k] === searchElement) { + return k; + } + k++; + } + return -1; + }; +} diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/services.js b/samples/ConferenceApp/BeyondSessionsApp/client/services.js new file mode 100644 index 0000000..985c3a2 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/services.js @@ -0,0 +1,240 @@ + +var app = angular.module("sessionsApp.services", []); + +app.factory('SessionsFactory', function($http, $q, sessionsRestUrl, favoritesRestUrl, utils, localStorageService) { + + var favorites = []; + var favoritesLoaded = false; + + //retrieve a specific data type from the localStorage (cached for 60 minutes) + getFromLocalCache = function(item) { + + var lastUpdate = localStorageService.get( item + 'LastUpdate' ); + + if (lastUpdate != null) { + + var now = (new Date()).getTime(); + var diff = (now - lastUpdate ) / 1000; + + //console.log('found ' + item + ' in cache, last update: ' + diff + ' seconds ago'); + + if (diff < (3600*2)) { //cache sessions for 2 hours + return localStorageService.get(item); + } + + } + + return null; + + }; + + getAllSessions = function() { + + var res = getFromLocalCache('sessions'); + + if (res != null) { + var deferred = $q.defer(); + deferred.resolve(res); + return deferred.promise; + } + + return $http.get(sessionsRestUrl + 'collections/name/sessionsAll?count=1000') + .then (function(res) { + + localStorageService.set('sessions', res.data); + localStorageService.set('sessionsLastUpdate', (new Date()).getTime() ); + + return res.data; + + }); + + }; + + return { + + all : function() { + + return getAllSessions() + .then( function(res) { + return res; + }); + + }, + + getByDay : function(dayNo) { + + return getAllSessions() + .then( function(res) { + + var filtered = []; + angular.forEach( res, function(session) { + if (session.dayNo == dayNo) { + filtered.push(session); + } + }); + return filtered; + }); + + }, + + getByTrack : function(track) { + + return getAllSessions() + .then( function(res) { + + var filtered = []; + angular.forEach( res, function(session) { + if (session.track == track) { + filtered.push(session); + } + }); + return filtered; + }); + + }, + + getByID : function(sessionId) { + + return getAllSessions() + .then( function(res) { + + for (var i=0; i -1; + }; + + $scope.getBackgroundClass = function(track) { + return "bg-" + utils.getColorForTrack(track); + }; + +}); + +sessionsAppCtrl.controller( "SessionsCtrl", function($scope, SessionsFactory, utils, $controller) { + + // instantiate base controller + $controller('SessionsBaseCtrl', { $scope: $scope }); + + SessionsFactory.all().then( function(sessions) { + $scope.sessions = sessions; + $scope.isLoading = false; + + //get favorites + if ( utils.hasFavorites() ) { + SessionsFactory.getFavorites().then( function(favorites) { + $scope.favorites = favorites; + }); + } + + }); + +}); + +sessionsAppCtrl.controller( "SessionsByDayCtrl", function($scope, $stateParams, SessionsFactory, utils, $controller) { + + // instantiate base controller + $controller('SessionsBaseCtrl', { $scope: $scope }); + + SessionsFactory.getByDay($stateParams.dayNo).then( function(sessions) { + $scope.sessions = sessions; + $scope.isLoading = false; + + //get favorites + if ( utils.hasFavorites() ) { + SessionsFactory.getFavorites().then( function(favorites) { + $scope.favorites = favorites; + }); + } + }); + +}); + +sessionsAppCtrl.controller( "SessionsByTrackCtrl", function($scope, $stateParams, SessionsFactory, utils, $controller) { + + // instantiate base controller + $controller('SessionsBaseCtrl', { $scope: $scope }); + + $scope.allowSearch = false; + + /*$scope.trackFilter = function(item) { + return item.track.indexOf($stateParams.trackId)>-1; + };*/ + + SessionsFactory.getByTrack($stateParams.trackId).then( function(sessions) { + $scope.sessions = sessions; + $scope.isLoading = false; + + //get favorites + if ( utils.hasFavorites() ) { + SessionsFactory.getFavorites().then( function(favorites) { + $scope.favorites = favorites; + }); + } + }); + +}); + +sessionsAppCtrl.controller( "NowNextCtrl", function($scope, SessionsFactory, utils, $controller) { + + // instantiate base controller + $controller('SessionsBaseCtrl', { $scope: $scope }); + + $scope.sessionsNow = []; + $scope.sessionsNext =[]; + + var now = new Date(); + + //debug + now.setYear(2014); + now.setMonth(0); + now.setDate(29); + + //v/ar nowMs = now.getTime(); + var todayDayNo = now.getDay(); + + SessionsFactory.getByDay(todayDayNo).then( function(sessions) { + + angular.forEach(sessions, function(session) { + + var s = new Date(session.startTime); + var e = new Date(session.endTime); + + //console.log('session', s, e, now); + + //restrict list of sessions to sessions running now/ next + if (s > now) { + + //calculate time between now & session start + var diffMs = (s - now); // milliseconds between now & start + session.startsIn = Math.round( diffMs / 1000 / 60 ); //minutes to start + + if (session.startsIn < 120 ) { //only add sessions that start in the next 2 hours + $scope.sessionsNext.push(session); + } + + } else if (s < now && e > now ) { + //this session has started: calculate remaining no of minutes + + var diffRuns = (e - now); + session.runsFor = Math.round(diffRuns / 1000 / 60); + + $scope.sessionsNow.push(session); + } + + }); + + $scope.isLoading = false; + }); + +}); + +sessionsAppCtrl.controller( "FavoritesCtrl", function($scope, SessionsFactory, utils, $controller) { + + // instantiate base controller + $controller('SessionsBaseCtrl', { $scope: $scope }); + + $scope.sessions = []; + $scope.allowSearch = false; + $scope.noDocsFound = "You don't have any favorites yet..."; + + if ( utils.hasFavorites() ) { + + SessionsFactory.getFavorites().then( function(fav) { + + $scope.favorites = fav; + + //get all sessions, restrict to favorites + SessionsFactory.all().then( function(sessions) { + + var favoriteSessions = []; + + for (var i=0; i-1) { + favoriteSessions.push( sessions[i] ); + } + + } + + $scope.sessions = favoriteSessions; + $scope.isLoading = false; + }); + + }); + } + + SessionsFactory.all().then( function(sessions) { + //$scope.sessions = sessions; + $scope.isLoading = false; + }); + + +}); + +sessionsAppCtrl.controller( "SessionCtrl", function($controller, $scope, $stateParams, SessionsFactory, utils) { + + // instantiate base controller + $controller('SessionsBaseCtrl', { $scope: $scope }); + + $scope.toggleFavorite = function() { + + var sessionId = $scope.session.sessionId; + + //check if we have a UNID we can store the favorites in (on the server) + var favoritesUnid = utils.getFavoritesUnid(); + + if ($scope.session.isFavorite) { + + $scope.session.isFavorite = false; + + var pos = $scope.favorites.indexOf( sessionId); + + if (pos>-1){ + $scope.favorites.splice(pos, 1); + } + + SessionsFactory.saveFavorites(favoritesUnid, $scope.favorites); + + } else { + + //mark as favorite + $scope.session.isFavorite = true; + $scope.favorites.push( sessionId ); + + //console.log('adding favorite', $scope.session.sessionId, 'all favorites:', $scope.favorites ); + + //TODO: make list unique + + //get the unid of this users' favorites document from localStorage + //if no id exists, a new favorite document is created using DDS + //and the unid of that document is stored locally. + + if ( favoritesUnid == null || favoritesUnid.length==0 ) { + //no favorites yet: get favorites unid + + SessionsFactory.getFavoritesUnid() + .then( function(favoritesUnid) { + + utils.setFavoritesUnid(favoritesUnid); + + //now store the favorites list + SessionsFactory.saveFavorites(favoritesUnid, $scope.favorites); + + }); + + } else { + + //console.log('existing favorites unid ' + favoritesUnid); + + //store the favorites + SessionsFactory.saveFavorites(favoritesUnid, $scope.favorites); + } + + + } + + }; + + SessionsFactory.getByID($stateParams.sessionId) + .then( function(session) { + $scope.session = session; + $scope.isLoading = true; + + //check if the session is a favorite + if ( utils.hasFavorites() ) { + SessionsFactory.getFavorites(true).then( function(favorites) { + //console.log('check favs', favorites, session.sessionId); + + if (favorites.indexOf(session.sessionId)>-1) { + $scope.session.isFavorite = true; + } + + $scope.favorites = favorites; + }); + } + }); + +}); + +sessionsAppCtrl.controller('FeedbackCtrl', function($scope, SessionsFactory) { + + $scope.submitted = false; + + $scope.submit = function() { + + SessionsFactory.saveFeedback( {feedback : $scope.feedback, name: $scope.name} ); + $scope.submitted = true; + + }; + +}); + + diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/styles.css b/samples/ConferenceApp/BeyondSessionsApp/client/styles.css new file mode 100644 index 0000000..1910d8e --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/styles.css @@ -0,0 +1,231 @@ +/* + background-color: http://www.google.com/design/spec/style/color.html#color-color-palette; + colors: see */ + +/*top padding for the static navbar*/ +body { + padding-top: 57px; +} + +/*no gutter on lists on small devices*/ +@media (max-width: 767px) { + .no-gutter > [class*='col-'] { + padding-right:0; + padding-left:0; + } + + /*no borders on panels (sessions)*/ + .panel { + border: 0; + } + + /*remove the border on smartphones*/ + .sessions .list-group-item { + border-left: 0; + border-right: 0; + } +} + +/*session title text size*/ +.sessions .list-group-item .list-group-item-heading { + font-size: 15px; +} + +/*make room in the sessions list for the track color*/ +.sessions .list-group-item { + padding-left: 19px; +} + +/*margin in buttons > icons*/ +.btn > i.fa, a > i.fa, .offcanvas i.fa, i.fa-refresh { + margin-right: 4px; +} + +/*for icon only buttons */ +.btn i.no-text { + margin-right: 0; +} + +/*margin on the navbar toggle button*/ +.navbar-toggle { + margin-left: 10px; + margin-right: 0; +} + +/*get rid of the rounded corners*/ +.btn, .panel, .panel-heading, .form-control, +.list-group-item:first-child, .list-group-item:last-child, .alert { + border-radius: 0; +} + +/*highlight active menu option*/ +.nav>li.active>a { + text-decoration: none; + background-color: #EEE; +} + +/*offcanvas*/ +.offcanvas, .offcanvas-list { + background: #ffffff; + position: fixed; + top: 57px; + bottom: 0; + width: 200px; + overflow-y: auto; + z-index:1050; + height: 100%; + padding-bottom:63px; + border-right: 1px solid silver; + -webkit-transform: translate3d(0px, 0px, 0px); + -moz-transform: translate3d(0px, 0px, 0px); + -o-transform: translate3d(0px, 0px, 0px); + -ms-transform: translate3d(0px, 0px, 0px); + transform: translate3d(0px, 0px, 0px); +} + +/*offcanvas transitions*/ +.offcanvas, .container, .container:after { + -webkit-transition: 0.25s ease; + -moz-transition: 0.25s ease; + -o-transition: 0.25s ease; + transition: 0.25s ease; +} + +.offcanvas-left { + left: -200px; +} + .offcanvas-left.active, .container.active { + -webkit-transform: translate3d(200px, 0px, 0px); + -moz-transform: translate3d(200px, 0px, 0px); + -o-transform: translate3d(200px, 0px, 0px); + -ms-transform: translate3d(200px, 0px, 0px); + transform: translate3d(200px, 0px, 0px); +} + +/*size of menu items in the offcanvas*/ +.offcanvas li > a { + padding: 7px 10px; +} + +/*no scroll class gets added when the offcanvas is opened */ +body.noscroll { + overflow: hidden; + +} + +.container.active { + overflow: hidden; +} + +/*overlay for the container when the offcanvas is opened*/ +.container.active:after { + content: " "; + z-index: 10; + display: block; + position: absolute; + height: 100%; + top: 0; + left: 0; + right: 0; + background: rgba(0, 0, 0, 0.2); +} + +/*session details in the list*/ +.list-group-item-text { + line-height: 1.2; + font-size: 12px; + color: #8b8b8b; +} +.list-group-item .fa { + opacity: 0.4; + margin-top:5px; +} +.fa-star { + color: #F4CD00 !important; + opacity: 1 !important; +} + +/*sessions list*/ +.sessions .marker { + position:absolute; + top:0; + left:0; + height:100%; + width:10px; +} + +/*animate the 'favorite' button*/ +.btn-flip { + -webkit-animation: flip 0.4s; + -moz-animation: flip 0.4s; + -ms-animation: flip 0.4s; + animation: flip 0.4s; +} + +.msgBox.ng-hide-add { + -webkit-animation: fadeOut 0.5s; + display: block!important; +} +.msgBox.ng-hide-remove { + -webkit-animation: fadeIn 1.5s; +} + +/*view animation*/ +[ui-view].ng-enter { + -webkit-animation: fadeIn 0.4s; + -moz-animation: fadeIn 0.4s; + -ms-animation: fadeIn 0.4s; + animation: fadeIn 0.4s; +} + +/*text color on session*/ +.panel-default > .panel-heading { + color: #fff; +} +.track .fa { + color: #fff; +} + +/*track colors */ +.bg-green { + background-color: #259b24 !important; +} +.bg-lightgreen { + background-color: #8bc34a !important; +} +.bg-blue { + background-color: #536dfe !important;; +} +.bg-red { + background-color: #e51c23 !important; +} +.bg-yellow { + background-color: #ffff00 !important +} +.bg-orange { + background-color: #FF9800 !important;; +} +.bg-deeporange { + background-color: #ff5722 !important; +} +.bg-gray { + background-color: #607d8b !important;; +} +.bg-purple { + background-color: #673ab7 !important;; +} +.bg-amber { + background-color: #ffc107 !important;; +} +.bg-lime { + background-color: #cddc39 !important;; +} +.bg-pink { + background-color: #e91e63 !important;; +} +.bg-teal { + background-color: #009688 !important;; +} +.bg-cyan { + background-color: #18ffff !important; +} diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/templates.js b/samples/ConferenceApp/BeyondSessionsApp/client/templates.js new file mode 100644 index 0000000..879133a --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/templates.js @@ -0,0 +1,259 @@ +angular.module('templates-main', ['partials/about.html', 'partials/feedback.html', 'partials/map.html', 'partials/nownext.html', 'partials/session.html', 'partials/sessions.html']); + +angular.module("partials/about.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("partials/about.html", + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + " \n" + + "
\n" + + "\n" + + "

Hi!

\n" + + "

This is the demo app for our session at ConnectED 2015 in January in Orlando: \"The Future of Web Development - Write Once, Run Everywhere with AngularJS and Domino\". It is build using AngularJS and uses an IBM Domino backend.

\n" + + "\n" + + "

In our session we're going to talk about building web apps using the AngularJS JavaScript framework, with data coming from a Domino backend using REST. We will show you how an app built like this can run in multiple runtimes, like Domino, Bluemix, Connections, Microsoft Sharepoint and MobileFirst Foundation (previously Worklight).

\n" + + " \n" + + "

If you haven't registered for ConnectED yet: \n" + + " register now and we'll see you on Monday at 3:45 PM at the Swan - Toucan 1-2. It'll be worth it!\n" + + "

\n" + + "\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + " \n" + + "\n" + + "

Here comes the fine print...

\n" + + " \n" + + "

\n" + + " We did our best. Worked our ass off. But take absolutely no liability for the accurateness of the data in this app. Or if the app will work at all. It probably will. We hope (if it doesn't: please let us know). If you want the ConnectED session data used by this app in a comfortable Notes database, check out the Totally Unofficial Totally Unsupported IBM ConnectED Session Database by Mat Newman and others.\n" + + "

\n" + + "

\n" + + " Oh, and if you want to know more about how this app was built: talk to us if you see us walking around. That's what a conference is all about (you seriously thought it was the sessions?). We are not scary and will talk for beer \n" + + "

\n" + + "

\n" + + " This source code of this app is publicly available on GitHub.\n" + + "

\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
"); +}]); + +angular.module("partials/feedback.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("partials/feedback.html", + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "

\n" + + " We love to hear what you think about this app. Got remarks? Suggestions? Please let us know!\n" + + "

\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + "\n" + + "
\n" + + " \n" + + " \n" + + "
\n" + + "\n" + + "
\n" + + " \n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + " Got it. Thanks for that!\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "\n" + + "
\n" + + "\n" + + "
"); +}]); + +angular.module("partials/map.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("partials/map.html", + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + " \n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
"); +}]); + +angular.module("partials/nownext.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("partials/nownext.html", + "
\n" + + "
\n" + + "\n" + + "

Now ({{sessionsNow.length}})

\n" + + "\n" + + "
No sessions running at this time
\n" + + "\n" + + " \n" + + "\n" + + "

Next ({{sessionsNext.length}})

\n" + + "\n" + + "
Nothing's coming up. You're done for the day!
\n" + + "\n" + + " \n" + + "\n" + + "
\n" + + "
"); +}]); + +angular.module("partials/session.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("partials/session.html", + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "

{{session.title}}

\n" + + "
{{::session.startTimeDesc}} - {{::session.endTimeDesc}} in {{::session.room}} | {{::session.sessionId}}
\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + " \n" + + " \n" + + "\n" + + " Back\n" + + "
\n" + + "\n" + + "
\n" + + " {{::session.description}}\n" + + "
\n" + + "\n" + + " \n" + + "\n" + + "
Speakers
\n" + + "\n" + + "
\n" + + " \n" + + "
\n" + + " {{speaker}}\n" + + "
\n" + + " \n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + ""); +}]); + +angular.module("partials/sessions.html", []).run(["$templateCache", function($templateCache) { + $templateCache.put("partials/sessions.html", + "
\n" + + "\n" + + "
\n" + + "\n" + + "
\n" + + "
Loading...
\n" + + "
\n" + + "\n" + + "
{{noDocsFound}}
\n" + + "\n" + + " \n" + + "\n" + + "
\n" + + "\n" + + "
"); +}]); diff --git a/samples/ConferenceApp/BeyondSessionsApp/client/utils.js b/samples/ConferenceApp/BeyondSessionsApp/client/utils.js new file mode 100644 index 0000000..e671232 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/client/utils.js @@ -0,0 +1,81 @@ + +var utils = angular.module("sessionApp.utils", []); + +utils.factory('utils', function(localStorageService) { + + var favoritesCookieName = 'favoritesUnid'; + + return { + + hasFavorites : function() { + var favoritesUnid = this.getFavoritesUnid(); + var hasFavorites = favoritesUnid != null && favoritesUnid.length>0; + return hasFavorites; + }, + + getFavoritesUnid : function() { + return localStorageService.get('favoritesId'); + }, + + setFavoritesUnid : function(id) { + localStorageService.set('favoritesId', id); + }, + + getColorForTrack : function(trackName) { + + if (!trackName) { + return 'blue'; + } + + if (trackName.indexOf('Best Practices')>-1) { + return 'green'; + } else if (trackName.indexOf('Application Development')>-1) { + return 'amber'; + } else if (trackName.indexOf('Beyond')>-1) { + return 'red'; + } else if (trackName.indexOf('Spotlight')>-1) { + return 'gray'; + } else if (trackName.indexOf('Featured')>-1) { + return 'pink'; + } else if ( trackName.indexOf('Strategy') > -1) { + return 'deeporange'; + } else if ( trackName.indexOf('Partner') > -1) { + return 'teal'; + } else if ( trackName.indexOf('Partner') > -1) { + return 'purple'; + } else if ( trackName.indexOf('Infrastructure') > -1) { + return 'lightgreen'; + } else if (trackName.indexOf('Master Classes')>-1) { + return 'lime'; + } else { + console.log('no track color found for track ' + trackName); + return 'blue'; + } + }, + + getFullDayName : function(dayNo) { + + switch (dayNo) { + case '0': + return "Sunday"; + case '1': + return "Monday"; + case '2': + return "Tuesday"; + case '3': + return "Wednesday"; + case '4': + return "Thursday"; + case '5': + return "Friday"; + case '6': + return "Saturday"; + default: + return "?"; + } + + } + + }; + +}); \ No newline at end of file diff --git a/samples/ConferenceApp/BeyondSessionsApp/package.json b/samples/ConferenceApp/BeyondSessionsApp/package.json new file mode 100644 index 0000000..713a1a8 --- /dev/null +++ b/samples/ConferenceApp/BeyondSessionsApp/package.json @@ -0,0 +1,23 @@ +{ + "name": "connect15", + "version": "1.0.0", + "description": "", + "main": "Gruntfile.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "https://markleusink@bitbucket.org/markleusink/beyond-sessions-app.git" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "grunt": "^0.4.5", + "grunt-contrib-clean": "^0.6.0", + "grunt-contrib-concat": "^0.5.0", + "grunt-contrib-copy": "^0.7.0", + "grunt-html2js": "^0.2.9", + "grunt-contrib-watch": "^0.6.1" + } +} diff --git a/samples/ConferenceApp/DataInitializer.launch b/samples/ConferenceApp/DataInitializer.launch new file mode 100644 index 0000000..cef10e7 --- /dev/null +++ b/samples/ConferenceApp/DataInitializer.launch @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/samples/ConferenceApp/WebContent/.gitignore b/samples/ConferenceApp/WebContent/.gitignore new file mode 100644 index 0000000..1075100 --- /dev/null +++ b/samples/ConferenceApp/WebContent/.gitignore @@ -0,0 +1,6 @@ +client/bower_components/ +._.DS_Store +Thumbs.db +node_modules/ +build/ +/META-INF/ diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/addons.scss b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/addons.scss new file mode 100644 index 0000000..a5670b7 --- /dev/null +++ b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/addons.scss @@ -0,0 +1,7 @@ +/* This file is automatically managed and will be overwritten from time to time. */ +/* Do not manually edit this file. */ + +/* Import and include this mixin into your project theme to include the addon themes */ +@mixin addons { +} + diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/conferenceApp.scss b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/conferenceApp.scss new file mode 100644 index 0000000..89eeeef --- /dev/null +++ b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/conferenceApp.scss @@ -0,0 +1,411 @@ +// Global variable overrides. Must be declared before importing Valo. + +// Defines the plaintext font size, weight and family. Font size affects general component sizing. +//$v-font-size: 16px; +//$v-font-weight: 300; +//$v-font-family: "Open Sans", sans-serif; + +// Defines the border used by all components. +//$v-border: 1px solid (v-shade 0.7); +//$v-border-radius: 4px; + +// Affects the color of some component elements, e.g Button, Panel title, etc +//$v-background-color: hsl(210, 0%, 98%); +// Affects the color of content areas, e.g Panel and Window content, TextField input etc +//$v-app-background-color: $v-background-color; + +// Affects the visual appearance of all components +//$v-gradient: v-linear 8%; +//$v-bevel-depth: 30%; +//$v-shadow-opacity: 5%; + +// Defines colors for indicating status (focus, success, failure) +//$v-focus-color: valo-focus-color(); // Calculates a suitable color automatically +//$v-friendly-color: #2c9720; +//$v-error-indicator-color: #ed473b; + +// For more information, see: https://vaadin.com/book/-/page/themes.valo.html +// Example variants can be copy/pasted from https://vaadin.com/wiki/-/wiki/Main/Valo+Examples + +$v-luminance-threshold: 180 !default; + +$editor-background-color: #3b3f42 !default; +$valo-menu-background-color: $editor-background-color !default; + +$v-focus-color: rgb(96, 160, 234) !default; +$v-error-indicator-color: #eb2977 !default; +$v-friendly-color: rgb(54, 185, 85); + +$v-font-size: 15px !default; +$v-font-weight: 400 !default; +$v-unit-size: 32px !default; + +$login-info-width: 300px !default; +$login-info-opacity: 0.7 !default; +$login-background-color: $editor-background-color !default; +// Get more background images from unsplash.com (remember to optimize the filesize) +$login-background-image: "img/archetype-login-bg.jpg" !default; + +$editor-shadow: 0 0 10px 10px rgba(0,0,0,.1) !default; +$editor-embed-background-color: darken($editor-background-color, 5%) !default; +$editor-raised-background-color: lighten($editor-background-color, 10%) !default; +$editor-caption-font-color: valo-font-color($editor-background-color, 0.5) !default; + +$v-layout-margin-top: round($v-unit-size / 1.5) !default; +$v-layout-margin-right: $v-layout-margin-top !default; +$v-layout-margin-bottom: $v-layout-margin-top !default; +$v-layout-margin-left: $v-layout-margin-top !default; +$v-layout-spacing-vertical: round($v-unit-size / 1.8) !default; +$v-layout-spacing-horizontal: round($v-unit-size / 1.8) !default; + + +@import "../valo/valo.scss"; + + +@mixin conferenceApp { + @include valo; + + + // login screen - for small screens, see below + .login-screen { + background: $editor-background-color; + + @if $login-background-image { + background-image: url(#{$login-background-image}); + background-size: cover; + background-position: 50% 50%; + } + + width: 100%; + height: 100%; + + .login-form { + @include valo-panel-style; + border: none; + padding: $v-layout-margin; + @include valo-animate-in-fade($duration: 1s); + } + + .login-information { + display: inline-block; + position: absolute; + top: 0; + left: 0; + width: $login-info-width; + height: 100%; + background: $v-selection-color; // For IE8 + background-color: rgba($v-selection-color, $login-info-opacity); + padding: $v-layout-margin; + color: valo-font-color($v-selection-color, 0.9); + @include animation(valo-animate-in-fade 1s 1s backwards); + + h1 { + color: inherit; + } + } + + .centering-layout { + display: inline-block; + width: 100%; + height: 100%; + padding-left: $login-info-width; + + .v-slot { + height: 100%; + } + } + } + + // makes the CRUD view keep the sidebar editor within the view as sidebar is absolutely positioned + .crud-view { + position: relative; + + .filter-textfield { + width: round($v-unit-size * 9); + } + } + + // sidebar editor for CRUD, scrolls if there is not enough space vertically + .product-form-wrapper { + position: absolute; + top: 0; + bottom: 0; + right: 0; + z-index: 100; + width: round($v-unit-size * 9); + height: 100%; + overflow: auto; + padding: $v-layout-spacing-vertical $v-layout-spacing-horizontal; + background-color: $editor-background-color; + color: valo-font-color($editor-background-color, 0.8); + + // Set the context color for the style mixins + $temp: $v-app-background-color; + $v-app-background-color: $editor-background-color; + + .v-textfield { + @include valo-textfield-style($background-color: $editor-embed-background-color); + } + + .v-checkbox { + @include valo-checkbox-style($background-color: $editor-raised-background-color); + } + + .v-filterselect { + @include valo-combobox-style($background-color: $editor-raised-background-color, $bevel: $v-bevel, $gradient: $v-gradient); + } + + // Restore variable + $v-app-background-color: $temp; + + .v-button { + display: block; + } + + .v-caption { + color: $editor-caption-font-color; + } + + // try to ensure there is space under the last button also on small displays (does not work on IE8) + .form-layout > .v-expand > .v-slot:last-child { + padding-bottom: $v-layout-spacing-vertical; + } + + @include transition(all 300ms); + @include transform(translatex(100%)); + } + + // Enables animation for opening CRUD editor + .visible { + @include transform(none); + @include box-shadow($editor-shadow); + } + + // About view + + .about-view { + overflow: auto; + + .about-content { + @include valo-panel-style; + max-width: 500px; + // Override the default of CustomLayout + padding: $v-unit-size !important; + } + } + + // Style rules for smaller display sizes + + // No top menu on the login view, login screen layout changes + .v-ui[width-range~="0-800px"] { + + .main-screen { + padding-top: $v-unit-size; + } + // TODO also move loading indicator if using the hack above + + // More compact login screen + .login-screen { + height: auto; + min-height: 100%; + + .login-information { + position: static; + width: 100%; + height: auto; + + .v-label { + text-align: center; + + h1 { + margin-top: .4em; + } + } + } + + .centering-layout { + display: block; + width: 100%; + height: auto; + padding-left: 0; + padding-top: 60px; + padding-bottom: 60px; + } + + .login-form { + width: 400px; + max-width: 100%; + + table { + width: 100%; + } + + .v-textfield { + width: 100% !important; + } + + .v-formlayout-captioncell, + .v-formlayout-contentcell, + .v-formlayout-errorcell { + display: block; + text-align: center; + padding-top: 0; + } + .buttons { + width: 100%; + .v-button { + display: block; + text-align: center; + } + } + } + } + } + + // hide the logo for a more compact header when the menu is narrow + .v-ui[width-range~="801px-1100px"] .valo-menu-part { + .v-slot-logo, + .v-slot-logo + .v-spacing { + display: none; + } + } + + // Move logout button to the bottom of the menu on large screens + .v-ui[width-range~="801px-"] .valo-menu-part { + .user-menu { + position: fixed; + bottom: 0; + margin-bottom: 0; + } + } + + // Editor should take whole browser width when we are under 550px in width. + .v-ui[width-range~="0-550px"] { + .product-form-wrapper { + width:100%; + } + + // Remove margins around the grid and reduce top bar margins on small screens + .crud-view .crud-main-layout { + padding: 0 0 0 0; + + .top-bar { + // Use spacing to the grid below as the margin - smaller than default margin + padding: $v-layout-spacing-vertical $v-layout-spacing-horizontal 0 $v-layout-spacing-horizontal; + + .filter-textfield { + width: 100%; + } + } + } + + // About view fills the display on small screens + .about-view { + padding-bottom: 0; + padding-top: 0; + height: auto; + padding: 0.1 * $v-unit-size; + + .v-slot-about-content { + overflow: auto; + } + + .about-content { + width: 100%; + max-width: 100%; + height: auto; + vertical-align: top; + padding: 0; + background: transparent; + @include box-shadow(none); + } + } + } + + // Override valo default narrow menu button on small screens to have the full logout text visible + .v-ui[width-range~="0-500px"] { + .valo-menu .v-menubar-user-menu .v-menubar-menuitem-caption { + width: auto; + } + } + + // Hide spinner buttons from number input + input[type=number]::-webkit-inner-spin-button, + input[type=number]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; + } + + // For aligning in grid until #15438 is done + .align-right { + text-align: right; + } + + .v-grid-header th { + color: #fff; + } + + .v-grid-header .v-grid-cell { + background-image: none; + background-color: #60a0ea; + } + +.v-grid-cell { + height: 65px; + word-wrap: break-word; + white-space: normal; +} + +.v-slot-menuArea { + background-color: #3b3f42; + background-image: linear-gradient(to left, #313537 0%, #3b3f42 8px); +} + +.v-menubar .v-menubar-menuitem { + background-color: #3b3f42; + background-image: linear-gradient(to left, #313537 0%, #3b3f42 8px); + color: #9b9fa3; +} + +.v-menubar .v-menubar-menuitem-highlight { + background-color: #9b9fa3; + color: #3b3f42; +} + +.v-menubar-popup .v-menubar-menuitem { + background-color: #3b3f42; + background-image: linear-gradient(to left, #313537 0%, #3b3f42 8px); + color: #9b9fa3; +} + +.v-menubar-popup .v-menubar-menuitem-highlight { + background-color: #9b9fa3; + color: #3b3f42; +} + +.valo-menu-subtitle { + margin: 0px; + box-sizing: none; + border: 0px; + background-color: #3b3f42; + background-image: none; + box-shadow: none; +} + +/* Lay the options horizontally */ +.v-select-optiongroup-horizontal .v-select-option { + display: inline-block; +} + +/* Avoid wrapping if the layout is too tight */ +.v-select-optiongroup-horizontal { + white-space: nowrap; +} + +/* Some extra spacing is needed */ +.v-select-optiongroup-horizontal + .v-select-option.v-radiobutton { + padding-right: 10px; +} + +} \ No newline at end of file diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/favicon.ico b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/favicon.ico new file mode 100644 index 0000000..140123c Binary files /dev/null and b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/favicon.ico differ diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/archetype-login-bg.jpg b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/archetype-login-bg.jpg new file mode 100644 index 0000000..a6a411d Binary files /dev/null and b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/archetype-login-bg.jpg differ diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/engage_logo.png b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/engage_logo.png new file mode 100644 index 0000000..a458fb1 Binary files /dev/null and b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/engage_logo.png differ diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/table-logo.png b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/table-logo.png new file mode 100644 index 0000000..a3e9c0f Binary files /dev/null and b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/img/table-logo.png differ diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/layouts/aboutview.html b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/layouts/aboutview.html new file mode 100644 index 0000000..2d200cc --- /dev/null +++ b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/layouts/aboutview.html @@ -0,0 +1,15 @@ + + + + + + + +

About

+ +
+ +Vaadin web page + + + \ No newline at end of file diff --git a/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/styles.scss b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/styles.scss new file mode 100644 index 0000000..74c79f1 --- /dev/null +++ b/samples/ConferenceApp/WebContent/VAADIN/themes/conferenceApp/styles.scss @@ -0,0 +1,13 @@ +@import "conferenceApp.scss"; +@import "addons.scss"; + +// This should be in the Valo theme as a shorthand +$v-layout-margin: $v-layout-margin-top $v-layout-margin-right $v-layout-margin-bottom $v-layout-margin-left !default; + +// This file prefixes all rules with the theme name to avoid causing conflicts with other themes. +// The actual styles should be defined in mockapp.scss + +.conferenceApp { + @include addons; + @include conferenceApp; +} diff --git a/samples/ConferenceApp/WebContent/WEB-INF/.gitignore b/samples/ConferenceApp/WebContent/WEB-INF/.gitignore new file mode 100644 index 0000000..840e7d3 --- /dev/null +++ b/samples/ConferenceApp/WebContent/WEB-INF/.gitignore @@ -0,0 +1 @@ +/classes/ diff --git a/samples/ConferenceApp/WebContent/WEB-INF/ibm-web-ext.xml b/samples/ConferenceApp/WebContent/WEB-INF/ibm-web-ext.xml new file mode 100644 index 0000000..2990a96 --- /dev/null +++ b/samples/ConferenceApp/WebContent/WEB-INF/ibm-web-ext.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/samples/ConferenceApp/WebContent/WEB-INF/web.xml b/samples/ConferenceApp/WebContent/WEB-INF/web.xml new file mode 100644 index 0000000..0c13565 --- /dev/null +++ b/samples/ConferenceApp/WebContent/WEB-INF/web.xml @@ -0,0 +1,48 @@ + + + ConnectedWorld + + + JAX-RS Tools Generated - Do not modify + JAX-RS Servlet + com.ibm.websphere.jaxrs.server.IBMRestServlet + 1 + true + false + + + org.openntf.conferenceapp.rest.ConnectedApplication + /api/* + + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + + + This is the description for the sample servlet + + + + icons/small.gif + icons/small.gif + + + org.openntf.conferenceapp.rest.ConnectedApplication + + + + org.openntf.crossworlds.devtimename + CN=Daniele Vistalli/O=Factor-y/C=IT + + + org.atmosphere.cpr.SessionSupport + + org.atmosphere.cpr.SessionSupport + + + \ No newline at end of file diff --git a/samples/ConferenceApp/build-graph.xml b/samples/ConferenceApp/build-graph.xml new file mode 100644 index 0000000..e252c5c --- /dev/null +++ b/samples/ConferenceApp/build-graph.xml @@ -0,0 +1,30 @@ + + + + + description + + + + + + + + + + + + + + diff --git a/samples/ConferenceApp/pom.xml b/samples/ConferenceApp/pom.xml new file mode 100644 index 0000000..acd59d3 --- /dev/null +++ b/samples/ConferenceApp/pom.xml @@ -0,0 +1,68 @@ + + 4.0.0 + org.openntf.xworlds.samples + ConferenceApp + 0.0.1-SNAPSHOT + war + + + org.openntf.xworlds.webapp + j2eeenabler + 0.0.1-SNAPSHOT + + + com.ibm.tools.target + was-liberty + LATEST + pom + provided + + + com.vaadin + vaadin-server + 7.4.1 + + + com.vaadin + vaadin-push + 7.4.1 + + + com.vaadin + vaadin-client-compiled + 7.4.1 + + + com.vaadin + vaadin-themes + 7.4.1 + + + org.apache.commons + commons-email + 1.3.3 + + + + + src + + + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + + + maven-war-plugin + 2.4 + + WebContent + false + + + + + \ No newline at end of file diff --git a/samples/ConferenceApp/src/com/factor_y/util/crypto/DesEncrypter.java b/samples/ConferenceApp/src/com/factor_y/util/crypto/DesEncrypter.java new file mode 100644 index 0000000..0717407 --- /dev/null +++ b/samples/ConferenceApp/src/com/factor_y/util/crypto/DesEncrypter.java @@ -0,0 +1,145 @@ +package com.factor_y.util.crypto; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.KeySpec; +import java.util.logging.Logger; + +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; + +import com.google.common.io.BaseEncoding; + + +public class DesEncrypter { + + private static final Logger log = Logger.getLogger(DesEncrypter.class.getName()); + + Cipher ecipher; + Cipher dcipher; + + final static String ALGORITHM="PBEWithMD5AndDES"; + + + // Iteration count + int iterationCount = 19; + + public DesEncrypter(Long seed,String passPhrase) throws DesEncrypterException { + log.info("Initializing DES Password Based Encrypter based on alg: "+ALGORITHM); + log.info("Passphrase: "+passPhrase + " len: " + passPhrase.length()); + try { + /* + Random rand = new Random(seed); + byte[] salt = new byte[8]; + rand.nextBytes(salt); + */ + byte[] seedAsByte = seed.toString().getBytes(); + MessageDigest algorithm = MessageDigest.getInstance("MD5"); + algorithm.reset(); + algorithm.update(seedAsByte); + byte messageDigest[] = algorithm.digest(); + + if(messageDigest.length<8){ + throw new DesEncrypterException("Seed is too short"); + } + byte[] salt = new byte[8]; + for(int i =0;i getPlansToAttendEvents(); + + @AdjacencyUnique(label = PlansToAttend.LABEL) + public PlansToAttend addPlansToAttend(Event event); + + @AdjacencyUnique(label = PlansToAttend.LABEL) + public void removePlansToAttend(Event event); + + @IncidenceUnique(label = PlansToAttend.LABEL) + public Iterable getPlansToAttend(); + + @IncidenceUnique(label = PlansToAttend.LABEL) + public void removePlansToAttend(PlansToAttend plansToAttend); + + @AdjacencyUnique(label = Attending.LABEL) + public Iterable getAttendingEvents(); + + @AdjacencyUnique(label = Attending.LABEL) + public Attending addAttending(Event event); + + @AdjacencyUnique(label = Attending.LABEL) + public void removeAttending(Event event); + + @IncidenceUnique(label = Attending.LABEL) + public Iterable getAttendings(); + + @IncidenceUnique(label = Attending.LABEL) + public void removeAttending(Attending attending); + + @AdjacencyUnique(label = PresentedBy.LABEL) + public Iterable getPresentingEvents(); + + @AdjacencyUnique(label = PresentedBy.LABEL) + public PresentedBy addPresentingEvent(Event event); + + @AdjacencyUnique(label = PresentedBy.LABEL) + public void removePresentingEvent(Event event); + + @IncidenceUnique(label = PresentedBy.LABEL) + public Iterable getPresentings(); + + @IncidenceUnique(label = PresentedBy.LABEL) + public void removePresenting(PresentedBy presentedBy); + + @AdjacencyUnique(label = InvitedTo.LABEL, direction = Direction.IN) + public Iterable getInvitedToInvites(); + + @AdjacencyUnique(label = InvitedTo.LABEL, direction = Direction.IN) + public Invites addInvitedTo(Invite invite); + + @AdjacencyUnique(label = InvitedTo.LABEL, direction = Direction.IN) + public void removeInvitedTo(Invite invite); + + @IncidenceUnique(label = InvitedTo.LABEL, direction = Direction.IN) + public Iterable getInvitedTos(); + + @IncidenceUnique(label = InvitedTo.LABEL, direction = Direction.IN) + public void removeInvitedTo(InvitedTo invitedTo); + + @AdjacencyUnique(label = Invites.LABEL) + public Iterable getInvitations(); + + @AdjacencyUnique(label = Invites.LABEL) + public Invites addInvitation(Invite invite); + + @AdjacencyUnique(label = Invites.LABEL) + public void removeInvitation(Invite invite); + + @IncidenceUnique(label = Invites.LABEL) + public Invites getInvites(); + + @IncidenceUnique(label = Invites.LABEL) + public void removeInvites(Invites invites); + + @AdjacencyUnique(label = MemberOf.LABEL) + public Iterable getMemberOfGroups(); + + @AdjacencyUnique(label = MemberOf.LABEL) + public MemberOf addMemberOfGroup(Group group); + + @AdjacencyUnique(label = MemberOf.LABEL) + public void removeMemberOfGroup(Group group); + + @IncidenceUnique(label = MemberOf.LABEL) + public Iterable getMemberOfs(); + + @IncidenceUnique(label = MemberOf.LABEL) + public void removeMemberOf(MemberOf memberOf); + + @AdjacencyUnique(label = ContactFor.LABEL) + public MemberOf addContactForSponsor(Sponsor sponsor); + + @AdjacencyUnique(label = ContactFor.LABEL) + public void removeContactForSponsor(Sponsor sponsor); +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/ConferenceGraph.java b/samples/ConferenceApp/src/org/openntf/conference/graph/ConferenceGraph.java new file mode 100644 index 0000000..03d6978 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/ConferenceGraph.java @@ -0,0 +1,156 @@ +package org.openntf.conference.graph; + +import java.util.List; + +import org.openntf.domino.graph2.builtin.social.Comment; +import org.openntf.domino.graph2.builtin.social.Likes; +import org.openntf.domino.graph2.builtin.social.Mentions; +import org.openntf.domino.graph2.builtin.social.Rates; +import org.openntf.domino.graph2.impl.DConfiguration; +import org.openntf.domino.graph2.impl.DElementStore; +import org.openntf.domino.graph2.impl.DFramedGraphFactory; +import org.openntf.domino.graph2.impl.DFramedTransactionalGraph; +import org.openntf.domino.graph2.impl.DGraph; + +import com.google.common.collect.Lists; + +public class ConferenceGraph { + // public static final String ATTENDEE_PATH = "conference/attendees.nsf"; + // public static final String GROUP_PATH = "conference/groups.nsf"; + // public static final String EVENT_PATH = "conference/events.nsf"; + // public static final String INVITE_PATH = "conference/invites.nsf"; + // public static final String TIMES_PATH = "conference/times.nsf"; + // public static final String LOCATION_PATH = "conference/locations.nsf"; + // public static final String COMMENTS_PATH = "conference/comments.nsf"; + // public static final String SOCIAL_PATH = "conference/social.nsf"; + // public static final String DEFAULT_PATH = "conference/default.nsf"; + public static final String ATTENDEE_PATH = "conference/iconUk/attendees.nsf"; + public static final String GROUP_PATH = "conference/iconUk/groups.nsf"; + public static final String EVENT_PATH = "conference/iconUk/events.nsf"; + public static final String INVITE_PATH = "conference/iconUk/invites.nsf"; + public static final String TIMES_PATH = "conference/iconUk/times.nsf"; + public static final String LOCATION_PATH = "conference/iconUk/locations.nsf"; + public static final String COMMENTS_PATH = "conference/iconUk/comments.nsf"; + public static final String SOCIAL_PATH = "conference/iconUk/social.nsf"; + public static final String DEFAULT_PATH = "conference/iconUk/default.nsf"; + + private DFramedTransactionalGraph framedGraph_; + + public ConferenceGraph() { + initialize(); + } + + protected void initialize() { + DElementStore attendeeStore = new DElementStore(); + attendeeStore.setStoreKey(ATTENDEE_PATH); + attendeeStore.addType(Attendee.class); + DElementStore groupStore = new DElementStore(); + groupStore.setStoreKey(GROUP_PATH); + groupStore.addType(Group.class); + groupStore.addType(Sponsor.class); + DElementStore eventStore = new DElementStore(); + eventStore.setStoreKey(EVENT_PATH); + eventStore.addType(Event.class); + eventStore.addType(Presentation.class); + eventStore.addType(Social.class); + eventStore.addType(Meeting.class); + eventStore.addType(Track.class); + DElementStore inviteStore = new DElementStore(); + inviteStore.setStoreKey(INVITE_PATH); + inviteStore.addType(Invite.class); + DElementStore timesStore = new DElementStore(); + timesStore.setStoreKey(TIMES_PATH); + timesStore.addType(TimeSlot.class); + DElementStore commentStore = new DElementStore(); + commentStore.setStoreKey(COMMENTS_PATH); + commentStore.addType(Comment.class); + DElementStore locationStore = new DElementStore(); + locationStore.setStoreKey(LOCATION_PATH); + locationStore.addType(Location.class); + DElementStore socialStore = new DElementStore(); + socialStore.setStoreKey(SOCIAL_PATH); + socialStore.addType(Likes.class); + socialStore.addType(Rates.class); + socialStore.addType(Mentions.class); + DElementStore defaultStore = new DElementStore(); + defaultStore.setStoreKey(DEFAULT_PATH); + + DConfiguration config = new DConfiguration(); + DGraph graph = new DGraph(config); + config.addElementStore(attendeeStore); + config.addElementStore(groupStore); + config.addElementStore(eventStore); + config.addElementStore(inviteStore); + config.addElementStore(timesStore); + config.addElementStore(locationStore); + config.addElementStore(defaultStore); + config.setDefaultElementStore(defaultStore.getStoreKey()); + + // JavaHandlerModule jhm = new JavaHandlerModule(); + // Module module = config.getModule(); + DFramedGraphFactory factory = new DFramedGraphFactory(config); + framedGraph_ = (DFramedTransactionalGraph) factory.create(graph); + } + + public DFramedTransactionalGraph getFramedGraph() { + return framedGraph_; + } + + public Attendee getAttendee(final Object key, final boolean create) { + Attendee result = getAttendee(key); + if (result == null && create) { + result = getFramedGraph().addVertex(key, Attendee.class); + } + return result; + } + + public Attendee getAttendee(final Object key) { + Attendee result = null; + try { + result = getFramedGraph().getVertex(key, Attendee.class); + if (result == null) { + List verts = Lists.newArrayList(getFramedGraph().getVertices("Twitter", key, Attendee.class)); + if (!verts.isEmpty()) { + result = verts.get(0); + } else { + verts = Lists.newArrayList(getFramedGraph().getVertices("Email", key, Attendee.class)); + if (!verts.isEmpty()) { + verts.get(0); + } + } + } + return result; + } catch (Exception e) { + return null; + } + } + + public Group getGroup(final Object key, final boolean create) { + Group result = getGroup(key); + if (result == null && create) { + result = getFramedGraph().addVertex(key, Group.class); + } + return result; + } + + public Group getGroup(final Object key) { + return getFramedGraph().getVertex(key, Group.class); + } + + public T getEvent(final Object key) { + return (T) getFramedGraph().getVertex(key, Event.class); + } + + public TimeSlot getTimeSlot(final Object key) { + return getFramedGraph().getVertex(key, TimeSlot.class); + } + + public Iterable getTimeSlots() { + return getFramedGraph().getVertices(null, null, TimeSlot.class); + } + + public Location getLocation(final Object key) { + return getFramedGraph().getVertex(key, Location.class); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/DataDumper.java b/samples/ConferenceApp/src/org/openntf/conference/graph/DataDumper.java new file mode 100644 index 0000000..69e33fe --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/DataDumper.java @@ -0,0 +1,188 @@ +package org.openntf.conference.graph; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.TimeZone; + +import org.openntf.conference.graph.Group.Type; +import org.openntf.domino.Database; +import org.openntf.domino.Document; +import org.openntf.domino.View; +import org.openntf.domino.graph2.impl.DFramedTransactionalGraph; +import org.openntf.domino.graph2.impl.DGraph; +import org.openntf.domino.junit.TestRunnerUtil; +import org.openntf.domino.utils.Strings; + +import com.tinkerpop.frames.FramedTransactionalGraph; + +public class DataDumper implements Runnable { + private long marktime; + private static final String SRC_DATA_PATH = "OpenNTF Downloads/sphere2015.nsf"; + + public DataDumper() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + ConferenceGraph graph = new ConferenceGraph(); + DFramedTransactionalGraph framedGraph = graph.getFramedGraph(); + DGraph baseGraph = framedGraph.getBaseGraph(); + // Iterable vertices = baseGraph.getVertices("@", "Form=\"Presentation\""); + // //NTF There's no specific need to do it this way. I just wanted to test the TypeField-based framing + // + // for (Vertex vertex : vertices) { + // VertexFrame frame = framedGraph.frame(vertex, DVertexFrame.class); + // if (frame instanceof Presentation) { + // StringBuilder sb = new StringBuilder(); + // Map jsonMap = framedGraph.toJsonableMap(frame); + // for (String key : jsonMap.keySet()) { + // sb.append(key + ": \"" + String.valueOf(jsonMap.get(key)) + "\", "); + // } + // System.out.println("{" + sb.toString() + "}"); + // } + // } + long testEndTime = System.nanoTime(); + + SimpleDateFormat DATE_FORMAT_UK = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + DATE_FORMAT_UK.setTimeZone(TimeZone.getDefault()); + SimpleDateFormat DATE_FORMAT_EST = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + DATE_FORMAT_EST.setTimeZone(TimeZone.getTimeZone("EST")); + + Presentation pres = framedGraph.getVertex("ID114", Presentation.class); + Iterable times = pres.getTimes(); + for (TimeSlot ts : times) { + Calendar sTime = ts.getStartTime(); + Calendar eTime = ts.getEndTime(); + System.out.println("GMT Time: " + DATE_FORMAT_UK.format(sTime.getTime()) + " - " + DATE_FORMAT_UK.format(eTime.getTime())); + + System.out.println("EST Time: " + DATE_FORMAT_EST.format(sTime.getTime()) + " - " + DATE_FORMAT_EST.format(eTime.getTime())); + } + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + + } + + public void loadData(final org.openntf.domino.Session s, final FramedTransactionalGraph framedGraph) { + HashMap locs = new HashMap(); + HashMap tracks = new HashMap(); + try { + Database srcDb = s.getDatabase(s.getServerName(), SRC_DATA_PATH); + if (null == srcDb) { + throw new Exception("Source database not found on this Domino server at " + SRC_DATA_PATH); + } + + // Create Group vertexes + Group ibm_champion = framedGraph.addVertex("IBM Champions", Group.class); + ibm_champion.setType(Group.Type.PROGRAM); + + SimpleDateFormat sdf = new SimpleDateFormat(); + View sessions = srcDb.getView("Sessions"); + for (Document doc : sessions.getAllDocuments()) { + if (!doc.hasItem("$Conflict")) { // ignore conflicts + String locKey = doc.getItemValueString("Location"); + Location loc = framedGraph.addVertex(locKey, Location.class); + if (Strings.isBlankString(loc.getName())) { + loc.setName(doc.getItemValueString("Location")); + } + + String trackKey = doc.getItemValueString("Categories"); + Track track = framedGraph.addVertex(trackKey, Track.class); + if (Strings.isBlankString(track.getTitle())) { + track.setTitle(doc.getItemValueString("Categories")); + track.setDescription(doc.getItemValueString("Categories")); + } + + Date startDate = (Date) doc.getItemValue("StartDate", Date.class); + Date startDateTime = (Date) doc.getItemValue("StartDateTime", Date.class); + Date endDate = (Date) doc.getItemValue("EndDate", Date.class); + Date endDateTime = (Date) doc.getItemValue("EndDateTime", Date.class); + + Calendar startCal = new GregorianCalendar(TimeZone.getTimeZone("EST")); + startCal.setTime(startDate); + startCal.set(Calendar.HOUR, startDateTime.getHours()); + startCal.set(Calendar.MINUTE, startDateTime.getMinutes()); + startCal.set(Calendar.SECOND, startDateTime.getSeconds()); + + Calendar endCal = new GregorianCalendar(TimeZone.getTimeZone("EST")); + endCal.setTime(endDate); + endCal.set(Calendar.HOUR, endDateTime.getHours()); + endCal.set(Calendar.MINUTE, endDateTime.getMinutes()); + endCal.set(Calendar.SECOND, endDateTime.getSeconds()); + + String tsKey = sdf.format(startCal.getTime()) + " - " + sdf.format(endCal.getTime()); + TimeSlot ts = framedGraph.addVertex(tsKey, TimeSlot.class); + ts.setStartTime(startCal); + ts.setEndTime(endCal); + + String code = doc.getItemValueString("SessionID"); + // Not sure if I can combine these, that's for later + + Presentation sess = framedGraph.addVertex(code, Presentation.class); + sess.setTitle(doc.getItemValueString("Subject")); + sess.setDescription(doc.getItemValueString("Abstract")); + sess.setStatus(Event.Status.CONFIRMED); + sess.setSessionId(doc.getItemValueString("SessionID")); + sess.setLevel(doc.getItemValueString("Level")); + System.out.println("Assigning location - " + locKey + " to session " + doc.getItemValueString("Subject")); + sess.addLocation(loc); + track.addIncludesSession(sess); + + ts.addEvent(sess); + + for (int i = 1; i < 6; i++) { + String speaker = doc.getItemValueString("Speaker" + String.valueOf(i)); + if ("".equals(speaker)) { + break; + } + String speakerName = speaker; + String organization = ""; + if (speaker.contains(" - ")) { + int splitPos = speaker.indexOf(" - "); + speakerName = speaker.substring(0, splitPos); + organization = speaker.substring(splitPos + 3, speaker.length()); + } + Attendee att = framedGraph.addVertex(null, Attendee.class); + int sep = speakerName.indexOf(" "); + String firstName = speakerName.substring(0, sep); + String lastName = speakerName.substring(sep + 1, speakerName.length()); + att.setFirstName(firstName); + att.setLastName(lastName); + + if (!"".equals(organization)) { + Group org = framedGraph.addVertex(organization, Group.class); + org.setName(organization); + org.setType(Type.COMPANY); + org.addMember(att); + } + + sess.addPresentedBy(att); + sess.addAttendingAttendee(att); + sess.addPlansToAttend(att); + } + + } + + } + framedGraph.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new DataDumper(), TestRunnerUtil.NATIVE_SESSION); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerConnectED.java b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerConnectED.java new file mode 100644 index 0000000..15d69ca --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerConnectED.java @@ -0,0 +1,201 @@ +package org.openntf.conference.graph; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.TimeZone; + +import org.openntf.conference.graph.Group.Type; +import org.openntf.domino.Database; +import org.openntf.domino.DateTime; +import org.openntf.domino.Document; +import org.openntf.domino.Session; +import org.openntf.domino.View; +import org.openntf.domino.graph2.impl.DGraph; +import org.openntf.domino.junit.TestRunnerUtil; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; +import org.openntf.domino.utils.Strings; + +import com.tinkerpop.frames.FramedTransactionalGraph; + +public class DataInitializerConnectED implements Runnable { + private long marktime; + private static final String SRC_DATA_PATH = "OpenNTF Downloads/sphere2015.nsf"; + + public DataInitializerConnectED() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + timelog("Beginning dataInitializer..."); + + // Get / create databases + Session s = Factory.getSession(SessionType.NATIVE); + Database attendees = s.getDatabase(s.getServerName(), ConferenceGraph.ATTENDEE_PATH, true); + attendees.getAllDocuments().removeAll(true); + Database events = s.getDatabase(s.getServerName(), ConferenceGraph.EVENT_PATH, true); + events.getAllDocuments().removeAll(true); + Database groups = s.getDatabase(s.getServerName(), ConferenceGraph.GROUP_PATH, true); + groups.getAllDocuments().removeAll(true); + Database invites = s.getDatabase(s.getServerName(), ConferenceGraph.INVITE_PATH, true); + invites.getAllDocuments().removeAll(true); + Database location = s.getDatabase(s.getServerName(), ConferenceGraph.LOCATION_PATH, true); + location.getAllDocuments().removeAll(true); + Database times = s.getDatabase(s.getServerName(), ConferenceGraph.TIMES_PATH, true); + times.getAllDocuments().removeAll(true); + Database defaults = s.getDatabase(s.getServerName(), ConferenceGraph.DEFAULT_PATH, true); + defaults.getAllDocuments().removeAll(true); + + // Initialize the graph + ConferenceGraph graph = new ConferenceGraph(); + // graph.initialize(); //NTF already done in constructor + FramedTransactionalGraph framedGraph = graph.getFramedGraph(); + + loadData(s, framedGraph); + + Iterable pres = framedGraph.getVertices(null, null, Presentation.class); + + for (Presentation presentation : pres) { + System.out.println(presentation.getTitle()); + } + + } catch (Throwable t) { + t.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void loadData(final org.openntf.domino.Session s, final FramedTransactionalGraph framedGraph) { + HashMap locs = new HashMap(); + HashMap tracks = new HashMap(); + try { + Database srcDb = s.getDatabase(s.getServerName(), SRC_DATA_PATH); + if (null == srcDb) { + throw new Exception("Source database not found on this Domino server at " + SRC_DATA_PATH); + } + + // Create Group vertexes + Group ibm_champion = framedGraph.addVertex("IBM Champions", Group.class); + ibm_champion.setType(Group.Type.PROGRAM); + + SimpleDateFormat tempDf = new SimpleDateFormat(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + sdf.setTimeZone(TimeZone.getTimeZone("EST")); + View sessions = srcDb.getView("Sessions"); + for (Document doc : sessions.getAllDocuments()) { + if (!doc.hasItem("$Conflict")) { // ignore conflicts + String locKey = doc.getItemValueString("Location"); + Location loc = framedGraph.addVertex(locKey, Location.class); + if (Strings.isBlankString(loc.getName())) { + loc.setName(doc.getItemValueString("Location")); + } + + String trackKey = doc.getItemValueString("Categories"); + Track track = framedGraph.addVertex(trackKey, Track.class); + if (Strings.isBlankString(track.getTitle())) { + track.setTitle(doc.getItemValueString("Categories")); + track.setDescription(doc.getItemValueString("Categories")); + } + + Date sDate = (Date) doc.getItemValue("StartDate", Date.class); + DateTime sDateTime = (DateTime) doc.getItemValue("StartDateTime", DateTime.class); + Date eDate = (Date) doc.getItemValue("EndDate", Date.class); + DateTime eDateTime = (DateTime) doc.getItemValue("EndDateTime", DateTime.class); + + Date startDateTime = tempDf.parse(sDateTime.getLocalTime()); + startDateTime = sdf.parse(sdf.format(startDateTime)); + startDateTime.setYear(sDate.getYear()); + startDateTime.setMonth(sDate.getMonth()); + startDateTime.setDate(sDate.getDate()); + Calendar sDateCal = GregorianCalendar.getInstance(TimeZone.getTimeZone("EST")); + sDateCal.setTime(startDateTime); + + Date endDateTime = tempDf.parse(eDateTime.getLocalTime()); + endDateTime = sdf.parse(sdf.format(endDateTime)); + endDateTime.setYear(eDate.getYear()); + endDateTime.setMonth(eDate.getMonth()); + endDateTime.setDate(eDate.getDate()); + Calendar eDateCal = Calendar.getInstance(TimeZone.getTimeZone("EST")); + eDateCal.setTime(endDateTime); + + String tsKey = sdf.format(startDateTime) + " - " + sdf.format(endDateTime); + TimeSlot ts = framedGraph.addVertex(tsKey, TimeSlot.class); + + ts.setStartTime(sDateCal); + ts.setEndTime(eDateCal); + + String code = doc.getItemValueString("SessionID"); + // Not sure if I can combine these, that's for later + + Presentation sess = framedGraph.addVertex(code, Presentation.class); + sess.setTitle(doc.getItemValueString("Subject")); + sess.setDescription(doc.getItemValueString("Abstract")); + sess.setStatus(Event.Status.CONFIRMED); + sess.setSessionId(doc.getItemValueString("SessionID")); + sess.setLevel(doc.getItemValueString("Level")); + System.out.println("Assigning location - " + locKey + " to session " + doc.getItemValueString("Subject")); + sess.addLocation(loc); + track.addIncludesSession(sess); + + ts.addEvent(sess); + + for (int i = 1; i < 6; i++) { + String speaker = doc.getItemValueString("Speaker" + String.valueOf(i)); + if ("".equals(speaker)) { + break; + } + String speakerName = speaker; + String organization = ""; + if (speaker.contains(" - ")) { + int splitPos = speaker.indexOf(" - "); + speakerName = speaker.substring(0, splitPos); + organization = speaker.substring(splitPos + 3, speaker.length()); + } + Attendee att = framedGraph.addVertex(null, Attendee.class); + int sep = speakerName.indexOf(" "); + String firstName = speakerName.substring(0, sep); + String lastName = speakerName.substring(sep + 1, speakerName.length()); + att.setFirstName(firstName); + att.setLastName(lastName); + + if (!"".equals(organization)) { + Group org = framedGraph.addVertex(organization, Group.class); + org.setName(organization); + org.setType(Type.COMPANY); + org.addMember(att); + } + + sess.addPresentedBy(att); + sess.addAttendingAttendee(att); + sess.addPlansToAttend(att); + } + + } + + } + framedGraph.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new DataInitializerConnectED(), TestRunnerUtil.NATIVE_SESSION); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerEngage.java b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerEngage.java new file mode 100644 index 0000000..571fa9d --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerEngage.java @@ -0,0 +1,220 @@ +package org.openntf.conference.graph; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; + +import org.openntf.domino.Database; +import org.openntf.domino.Session; +import org.openntf.domino.graph2.impl.DGraph; +import org.openntf.domino.junit.TestRunnerUtil; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; +import org.openntf.domino.utils.Strings; + +import com.ibm.commons.util.io.json.JsonJavaFactory; +import com.ibm.commons.util.io.json.JsonJavaObject; +import com.ibm.commons.util.io.json.JsonParser; +import com.tinkerpop.frames.FramedTransactionalGraph; + +public class DataInitializerEngage implements Runnable { + private long marktime; + private SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public DataInitializerEngage() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + timelog("Beginning dataInitializer..."); + + // Get / create databases + Session s = Factory.getSession(SessionType.NATIVE); + Database attendees = s.getDatabase(s.getServerName(), ConferenceGraph.ATTENDEE_PATH, true); + attendees.getAllDocuments().removeAll(true); + Database events = s.getDatabase(s.getServerName(), ConferenceGraph.EVENT_PATH, true); + events.getAllDocuments().removeAll(true); + Database groups = s.getDatabase(s.getServerName(), ConferenceGraph.GROUP_PATH, true); + groups.getAllDocuments().removeAll(true); + Database invites = s.getDatabase(s.getServerName(), ConferenceGraph.INVITE_PATH, true); + invites.getAllDocuments().removeAll(true); + Database location = s.getDatabase(s.getServerName(), ConferenceGraph.LOCATION_PATH, true); + location.getAllDocuments().removeAll(true); + Database times = s.getDatabase(s.getServerName(), ConferenceGraph.TIMES_PATH, true); + times.getAllDocuments().removeAll(true); + Database defaults = s.getDatabase(s.getServerName(), ConferenceGraph.DEFAULT_PATH, true); + defaults.getAllDocuments().removeAll(true); + + // Initialize the graph + ConferenceGraph graph = new ConferenceGraph(); + FramedTransactionalGraph framedGraph = graph.getFramedGraph(); + + loadData(s, framedGraph); + + Iterable pres = framedGraph.getVertices(null, null, Presentation.class); + + for (Presentation presentation : pres) { + System.out.println(presentation.getTitle()); + } + + } catch (Throwable t) { + t.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + private static String readUrl(final String urlString) throws Exception { + BufferedReader reader = null; + try { + URL url = new URL(urlString); + reader = new BufferedReader(new InputStreamReader(url.openStream())); + StringBuffer buffer = new StringBuffer(); + int read; + char[] chars = new char[1024]; + while ((read = reader.read(chars)) != -1) + buffer.append(chars, 0, read); + + return buffer.toString(); + } finally { + if (reader != null) + reader.close(); + } + } + + public void loadData(final org.openntf.domino.Session s, final FramedTransactionalGraph framedGraph) { + HashMap locs = new HashMap(); + HashMap tracks = new HashMap(); + HashMap trackLkup = new HashMap(); + trackLkup.put("Special", "Sp"); + trackLkup.put("Strategy/Deployment", "Str"); + trackLkup.put("Administration", "Adm"); + trackLkup.put("Development", "Dev"); + trackLkup.put("Business", "Bus"); + trackLkup.put("Commercial", "Comm"); + try { + String urlData = readUrl("http://xceed.be/engage.nsf/api/data/collections/name/BLUG_ViewSessions?start=0&count=100"); + + JsonJavaFactory factory = JsonJavaFactory.instanceEx; + + ArrayList jsonData = (ArrayList) JsonParser.fromJson(factory, urlData); + SimpleDateFormat sdf = new SimpleDateFormat(); + for (JsonJavaObject obj : jsonData) { + String locKey = obj.getAsString("session_room"); + Location loc = framedGraph.addVertex(locKey, Location.class); + if (Strings.isBlankString(loc.getName())) { + loc.setName(locKey); + } + + String trackKey = obj.getAsString("session_track"); + Track track = framedGraph.addVertex(trackLkup.get(trackKey), Track.class); + if (Strings.isBlankString(track.getTitle())) { + track.setTitle(trackLkup.get(trackKey)); + track.setDescription(trackKey); + } + + // DO DATES + String actualDate = obj.getAsString("session_date"); + String manipulated = actualDate.substring(0, 10) + " " + actualDate.substring(11, 19); + Date startDate = DATE_FORMAT.parse(manipulated); + String startTime = obj.getAsString("session_time1"); + String endTime = obj.getAsString("session_time2"); + Calendar startCal = Calendar.getInstance(); + startCal.setTime(startDate); + startCal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(Strings.left(startTime, ":"))); + startCal.set(Calendar.MINUTE, Integer.parseInt(Strings.right(startTime, ":"))); + startCal.set(Calendar.SECOND, 0); + startCal.set(Calendar.MILLISECOND, 0); + Calendar endCal = Calendar.getInstance(); + endCal.setTime(startDate); + endCal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(Strings.left(endTime, ":"))); + endCal.set(Calendar.MINUTE, Integer.parseInt(Strings.right(endTime, ":"))); + endCal.set(Calendar.SECOND, 0); + endCal.set(Calendar.MILLISECOND, 0); + + String tsKey = sdf.format(startCal.getTime()) + " - " + sdf.format(endCal.getTime()); + TimeSlot ts = framedGraph.addVertex(tsKey, TimeSlot.class); + ts.setStartTime(startCal); + ts.setEndTime(endCal); + ts.setOfficial(1); + + String code = obj.getAsString("session_nr"); + + Presentation sess = framedGraph.addVertex(code, Presentation.class); + sess.setTitle(obj.getAsString("session_title")); + sess.setDescription(obj.getAsString("session_abstract")); + sess.setStatus(Event.Status.CONFIRMED); + sess.setSessionId(code); + System.out.println("Assigning location - " + locKey + " to session " + obj.getAsString("session_title")); + sess.addLocation(loc); + track.addIncludesSession(sess); + + ts.addEvent(sess); + + for (int i = 1; i < 6; i++) { + String suffix = ""; + if (i > 1) { + suffix = Integer.toString(i); + } + String speaker = obj.getAsString("speaker_name" + suffix); + if ("".equals(speaker)) { + break; + } + String speakerName = speaker; + String organization = obj.getAsString("speaker_org" + suffix); + Attendee att = framedGraph.addVertex(speakerName, Attendee.class); + System.out.println(speaker); + int sep = speakerName.indexOf(" "); + if (sep > -1) { + String firstName = speakerName.substring(0, sep); + String lastName = speakerName.substring(sep + 1, speakerName.length()); + att.setFirstName(firstName); + att.setLastName(lastName); + } else { + att.setFirstName(speakerName); + } + att.setTwitterId(obj.getAsString("speaker_twitter" + suffix)); + att.setUrl(obj.getAsString("speaker_photourl" + suffix)); + att.setProfile(obj.getAsString("speaker_profile")); + + if (!"".equals(organization)) { + Group org = framedGraph.addVertex(organization, Group.class); + org.setName(organization); + org.setType(Group.Type.COMPANY); + org.addMember(att); + } + + sess.addPresentedBy(att); + sess.addAttendingAttendee(att); + sess.addPlansToAttend(att); + } + + } + + framedGraph.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new DataInitializerEngage(), TestRunnerUtil.NATIVE_SESSION); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerIconUk.java b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerIconUk.java new file mode 100644 index 0000000..f142868 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerIconUk.java @@ -0,0 +1,281 @@ +package org.openntf.conference.graph; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; + +import org.openntf.conference.graph.Sponsor.Level; +import org.openntf.domino.Database; +import org.openntf.domino.Session; +import org.openntf.domino.graph2.impl.DGraph; +import org.openntf.domino.junit.TestRunnerUtil; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; +import org.openntf.domino.utils.Strings; + +import com.ibm.commons.util.io.json.JsonJavaFactory; +import com.ibm.commons.util.io.json.JsonJavaObject; +import com.ibm.commons.util.io.json.JsonParser; +import com.tinkerpop.frames.FramedTransactionalGraph; + +public class DataInitializerIconUk implements Runnable { + private long marktime; + private SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM/yyyy HH:mm"); + + public DataInitializerIconUk() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + timelog("Beginning dataInitializer..."); + + // Get / create databases + Session s = Factory.getSession(SessionType.NATIVE); + Database attendees = s.getDatabase(s.getServerName(), ConferenceGraph.ATTENDEE_PATH, true); + attendees.getAllDocuments().removeAll(true); + Database events = s.getDatabase(s.getServerName(), ConferenceGraph.EVENT_PATH, true); + events.getAllDocuments().removeAll(true); + Database groups = s.getDatabase(s.getServerName(), ConferenceGraph.GROUP_PATH, true); + groups.getAllDocuments().removeAll(true); + Database invites = s.getDatabase(s.getServerName(), ConferenceGraph.INVITE_PATH, true); + invites.getAllDocuments().removeAll(true); + Database location = s.getDatabase(s.getServerName(), ConferenceGraph.LOCATION_PATH, true); + location.getAllDocuments().removeAll(true); + Database times = s.getDatabase(s.getServerName(), ConferenceGraph.TIMES_PATH, true); + times.getAllDocuments().removeAll(true); + Database defaults = s.getDatabase(s.getServerName(), ConferenceGraph.DEFAULT_PATH, true); + defaults.getAllDocuments().removeAll(true); + + // Initialize the graph + ConferenceGraph graph = new ConferenceGraph(); + FramedTransactionalGraph framedGraph = graph.getFramedGraph(); + + loadData(s, framedGraph); + + Iterable pres = framedGraph.getVertices(null, null, Presentation.class); + + for (Presentation presentation : pres) { + System.out.println(presentation.getTitle()); + } + + } catch (Throwable t) { + t.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + private static String readUrl(final String urlString) throws Exception { + BufferedReader reader = null; + try { + URL url = new URL(urlString); + reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8")); + + StringBuffer buffer = new StringBuffer(); + int read; + char[] chars = new char[1024]; + while ((read = reader.read(chars)) != -1) + buffer.append(chars, 0, read); + + return buffer.toString(); + } finally { + if (reader != null) + reader.close(); + } + } + + public void loadData(final org.openntf.domino.Session s, final FramedTransactionalGraph framedGraph) { + HashMap locs = new HashMap(); + locs.put("1", "Room 1"); + locs.put("2", "Room 2"); + locs.put("3", "Room 3"); + locs.put("4", "Room 4"); + HashMap tracks = new HashMap(); + HashMap trackLkup = new HashMap(); + trackLkup.put("6", "Management/Strategy"); + trackLkup.put("4", "Development"); + trackLkup.put("1", "Administration"); + trackLkup.put("3", "Beyond The Everyday"); + trackLkup.put("5", "ICON UK"); + int sessNo = 1; + try { + String urlData = readUrl("http://iconuk.org/iconuk/dragon/dragoniconuk2015.nsf/getAgendaICONUK.xsp?format=json"); + + JsonJavaFactory factory = JsonJavaFactory.instanceEx; + + JsonJavaObject jsonData = (JsonJavaObject) JsonParser.fromJson(factory, urlData); + + ArrayList jsonRecords = (ArrayList) jsonData.get("records"); + SimpleDateFormat sdf = new SimpleDateFormat(); + for (JsonJavaObject record : jsonRecords) { + JsonJavaObject obj = record.getAsObject("data"); + String locKey = obj.getAsString("session_locationNumber"); + Location loc = framedGraph.addVertex(locs.get(locKey), Location.class); + if (Strings.isBlankString(loc.getName())) { + loc.setName(locs.get(locKey)); + } + + String trackKey = obj.getAsString("session_tracknumber"); + Track track = framedGraph.addVertex(trackKey, Track.class); + if (Strings.isBlankString(track.getTitle())) { + track.setTitle(trackKey); + track.setDescription(trackLkup.get(trackKey)); + } + + // DO DATES + String date = obj.getAsString("session_daynumber"); + String actualDate; + if ("1".equals(date)) { + actualDate = "21/09/2015"; + } else { + actualDate = "22/09/2015"; + } + String time = obj.getAsString("session_time"); + String startTime = time.substring(0, 5); + String endTime = time.substring(8); + String manipulated = actualDate + " " + startTime; + Date startDate = DATE_FORMAT.parse(manipulated); + Calendar startCal = Calendar.getInstance(); + startCal.setTime(startDate); + startCal.set(Calendar.SECOND, 0); + startCal.set(Calendar.MILLISECOND, 0); + Calendar endCal = Calendar.getInstance(); + endCal.setTime(startDate); + endCal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(Strings.left(endTime, ":"))); + endCal.set(Calendar.MINUTE, Integer.parseInt(Strings.right(endTime, ":"))); + endCal.set(Calendar.SECOND, 0); + endCal.set(Calendar.MILLISECOND, 0); + + String tsKey = sdf.format(startCal.getTime()) + " - " + sdf.format(endCal.getTime()); + TimeSlot ts = framedGraph.addVertex(tsKey, TimeSlot.class); + ts.setStartTime(startCal); + ts.setEndTime(endCal); + ts.setOfficial(1); + + Presentation sess = framedGraph.addVertex(sessNo, Presentation.class); + sess.setTitle(obj.getAsString("session_name")); + sess.setDescription(obj.getAsString("session_abstract")); + sess.setStatus(Event.Status.CONFIRMED); + sess.setSessionId(Integer.toString(sessNo)); + System.out.println("Assigning location - " + loc.getName() + " to session " + obj.getAsString("session_name")); + sess.addLocation(loc); + track.addIncludesSession(sess); + + ts.addEvent(sess); + + for (int i = 1; i < 6; i++) { + String suffix = ""; + if (i > 1) { + suffix = Integer.toString(i); + } + String speaker = obj.getAsString("speaker_name" + suffix); + if ("".equals(speaker)) { + break; + } + String speakerName = speaker; + String organization = obj.getAsString("speaker_org" + suffix); + Attendee att = framedGraph.addVertex(speakerName, Attendee.class); + System.out.println(speaker); + int sep = speakerName.indexOf(" "); + if (sep > -1) { + String firstName = speakerName.substring(0, sep); + String lastName = speakerName.substring(sep + 1, speakerName.length()); + att.setFirstName(firstName); + att.setLastName(lastName); + } else { + att.setFirstName(speakerName); + } + + sess.addPresentedBy(att); + sess.addAttendingAttendee(att); + sess.addPlansToAttend(att); + } + + sessNo++; + + } + + // Now do speakers + urlData = readUrl("http://iconuk.org/iconuk/dragon/dragoniconuk2015.nsf/getspeakerdataICONUK.xsp?format=json"); + + jsonData = (JsonJavaObject) JsonParser.fromJson(factory, urlData); + + jsonRecords = (ArrayList) jsonData.get("records"); + for (JsonJavaObject record : jsonRecords) { + JsonJavaObject obj = record.getAsObject("data"); + + String speakerName = obj.getAsString("speaker_name"); + Attendee att = framedGraph.getVertex(speakerName, Attendee.class); + if (null != att) { + + att.setUrl(obj.getAsString("speaker_photourl")); + att.setProfile(obj.getAsString("speaker_bio")); + } + } + + // Now do sponsors + urlData = readUrl("http://iconuk.org/iconuk/dragon/dragoniconuk2015.nsf/getsponsordataICONUK.xsp"); + + jsonData = (JsonJavaObject) JsonParser.fromJson(factory, urlData); + + jsonRecords = (ArrayList) jsonData.get("records"); + for (JsonJavaObject record : jsonRecords) { + JsonJavaObject obj = record.getAsObject("data"); + String name = obj.getAsString("sponsor_name"); + String level = obj.getAsString("sponsor_level_value"); + String photoUrl = obj.getAsString("sponsor_logourl"); + String website = obj.getAsString("sponsor_website"); + String profile = obj.getAsString("sponsor_abstract"); + Level sponsorLevel = null; + if ("1".equals(level)) { + sponsorLevel = Level.PLATINUM; + } else if ("2".equals(level)) { + sponsorLevel = Level.GOLD; + } else if ("3".equals(level)) { + sponsorLevel = Level.SILVER; + } else if ("4".equals(level)) { + sponsorLevel = Level.BRONZE; + } + createSponsor(framedGraph, name, sponsorLevel, photoUrl, website, profile); + } + + framedGraph.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public Sponsor createSponsor(FramedTransactionalGraph framedGraph, String name, Level level, String photoUrl, String webUrl, + String profile) { + Sponsor org = null; + org = framedGraph.addVertex(name, Sponsor.class); + org.setName(name); + org.setType(Group.Type.COMPANY); + org.setLevel(level); + org.setPhotoUrl(photoUrl); + org.setUrl(webUrl); + org.setProfile(profile); + return org; + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new DataInitializerIconUk(), TestRunnerUtil.NATIVE_SESSION); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerSponsorsForEngage.java b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerSponsorsForEngage.java new file mode 100644 index 0000000..0e7b101 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/DataInitializerSponsorsForEngage.java @@ -0,0 +1,407 @@ +package org.openntf.conference.graph; + +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Map; + +import org.openntf.conference.graph.Sponsor.Level; +import org.openntf.domino.Session; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; +import org.openntf.domino.graph2.impl.DGraph; +import org.openntf.domino.junit.TestRunnerUtil; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; +import com.tinkerpop.blueprints.Vertex; +import com.tinkerpop.frames.FramedTransactionalGraph; + +public class DataInitializerSponsorsForEngage implements Runnable { + private long marktime; + private SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public DataInitializerSponsorsForEngage() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + timelog("Beginning dataInitializer..."); + + // Get / create databases + Session s = Factory.getSession(SessionType.NATIVE); + + // Initialize the graph + ConferenceGraph graph = new ConferenceGraph(); + FramedTransactionalGraph framedGraph = graph.getFramedGraph(); + + loadData(s, graph); + + Iterable groups = framedGraph.getVertices(null, null, Group.class); + + System.out.println("**Getting organisations**"); + for (Group group : groups) { + System.out.println(group.getName()); + } + Iterable orgs = framedGraph.getVertices(null, null, Sponsor.class); + System.out.println("Total sponsors: " + Lists.newArrayList(orgs).size()); + Ordering ord = Ordering.from(new DVertexFrameComparator("Level")); + List sponsors = ord.sortedCopy(orgs); + + System.out.println("**Getting sponsors**"); + for (Sponsor org : sponsors) { + System.out.println(org.getLevel().ordinal() + ": " + org.getName()); + } + + List groupsList = Lists.newArrayList(groups); + groupsList.addAll(Lists.newArrayList(orgs)); + System.out.println("**Getting organisations and sponsors**"); + for (Group group : groupsList) { + System.out.println(group.getName()); + } + + Attendee att = graph.getAttendee("Laurent Boes"); + if (null == att) { + System.out.println("Can't find Laurent"); + } else { + System.out.println("Found Laurent"); + List grps = Lists.newArrayList(att.getMemberOfGroups()); + System.out.println("Laurent member of group numbers: " + grps.size()); + for (Group group : grps) { + System.out.println(group.getName()); + System.out.println(group.hashCode()); + } + List presentations = Lists.newArrayList(att.getPresentingEvents()); + System.out.println("Presenting events: " + presentations.size()); + for (Event evt : presentations) { + System.out.println(evt.getTitle()); + } + + Map props = att.asMap(); + System.out.println("Outputting properties for Laurent Boes"); + for (CharSequence key : props.keySet()) { + System.out.println(key + " - " + props.get(key)); + } + } + + Iterable evts = framedGraph.getVertices(null, null, Event.class); + + } catch (Throwable t) { + t.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void loadData(final org.openntf.domino.Session s, final ConferenceGraph graph) { + try { + + // IBM Benelux + FramedTransactionalGraph framedGraph = graph.getFramedGraph(); + Sponsor org = createSponsor( + framedGraph, + "IBM Benelux", + Level.STRATEGIC, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/IBM.gif", + "http://www.ibm.com/social-business/us/en/", + "Businesses move from liking to leading when they look beyond social media to see how social technologies drive real business value. From marketing and sales to product and service innovation, social is changing the way people connect and the way organizations succeed. Social business technologies help people connect, communicate and share information. Becoming a leader in your marketplace means using social solutions to transform how business gets done—driving cost savings, increasing revenue and cultivating competitive advantages. IBM is at the forefront of this market shift and your best partner to get social and do business"); + addAttendee(graph, framedGraph, "Laurent", "Boes", "laurent_boes@be.ibm.com", org); + + Sponsor org2 = createSponsor( + framedGraph, + "BCC", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/BCC.gif", + "http://www.bcc.biz", + "BCC work with companies to secure their social business infrastructure, automate underlying administration processes and ensure regulatory compliance."); + addAttendee(graph, framedGraph, "Svenja", "Stolz", "svenja_stolzenbach@bcc.biz", org2); + + Sponsor org3 = createSponsor( + framedGraph, + "Crossware", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Crossware.gif", + "http://www.crossware.co.nz", + "Crossware Mail Signature gives you the ability to manage enterprise-wide email signatures. It is a server-based application that automatically adds compliant, personalised and attractive signatures to all emails, including those sent from mobile devices! Visit our booth to find out more and to be in to win a great prize!"); + addAttendee(graph, framedGraph, "Henry", "McIntosh", "henry@crossware.co.nz", org3); + + Sponsor org4 = createSponsor( + framedGraph, + "Cube Soft Consulting Ltd", + Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/CubeSoft.gif", + "http://www.cube-soft.co.uk", + "Cube Soft have over 15 years experience in working with Web, WebSphere, E-Commerce and Social Business based technologies and it is something we are passionate about. Our clients and customers are spread across the globe and based in the UK, USA, Canada and across Europe. We are an IBM™ Business partner specialising in IBM Connections™ , IBM WebSphere™ and other IBM Collaboration solutions – Our services include consultancy, installation, administration and training for the enterprise."); + addAttendee(graph, framedGraph, "Sharon", "Bellamy", "sharon@cube-soft.co.uk", org4); + + Sponsor org5 = createSponsor( + framedGraph, + "EASI", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Easi.gif", + "http://www.easi.net", + "EASI is editor of business software and apps. We realize software and mobile app development projects and provide IT infrastructure solutions and services both on premise and in the Cloud."); + addAttendee(graph, framedGraph, "Herman", "Clicq", "h.clicq@easi.net", org5); + + Sponsor org6 = createSponsor( + framedGraph, + "goodmeeting.biz", + Level.PLATINUM, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/GoodMeeting.gif", + "http://goodmeeting.biz", + "goodmeeting - The brilliant meeting software! (powered by WebGate Consulting AG) Meetings are named as top time killers. But meetings could be collaboration at it's best! Check out goodmeeting.biz"); + addAttendee(graph, framedGraph, "Roman", "Weber", "roman.weber@webgate.biz", org6); + + Sponsor org7 = createSponsor( + framedGraph, + "Groupwave", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Groupwave.gif", + "http://www.groupwave.be", + "Groupwave is specialized in ‘collaboration through communication’. The Lotus Portfolio is all about working together faster, better, stronger. Groupwave wants to take this one step further! We can integrate the provided Lotus solutions with VoIP thanks to our UC² knowledge. This is communication on another level! Mail, instant messaging, fax … are already widespread in the business. Telephony and VoIP are used on a daily basis. Integrating these two worlds is not the future, it is the present. Your communications will be more efficient and you will save time, which means money. Groupwave is also known for all its custom made applications. Not only websites, intranets, but also timesheet applications and … we build what customers need! Mobile apps and Xpages development have no secrets for us! Come over and speak to us so that we can guide you in defining the future of your IT environment."); + addAttendee(graph, framedGraph, "Kris", "De Bisschop", "kris.de.bisschop@groupwave.be", org7); + + Sponsor org8 = createSponsor( + framedGraph, + "HADSL", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Firm.gif", + "http://hadsl.com", + "Fed up with resetting passwords? Bored with setting up users for your HR department? Want to enrich your SPML id management system? Need ITIL or SOX compliance? HADSL FirM has been giving control to Domino Administrators for nearly 10 years. Using FirM to delegate creation, control and deletion of Domino User accounts and groups to the right people reduces mistakes and frees up your administrators’ time. FirM can also automatically manage your BlackBerry devices and links to Active Directory for seamless and secure user id creation and directory data synchronisation across your environments."); + addAttendee(graph, framedGraph, "Richard", "Sampson", "richard.sampson@hadsl.com", org8); + + Sponsor org9 = createSponsor( + framedGraph, + "hedersoft GmbH", + Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Hedersoft.gif", + "http://www.hedersoft.de", + "hedersoft is specialized on web and mobile development both inside and outside the IBM universe. Our products: - hedersoft Crawler: Easily search data sources for updates and post them either to an activity stream or create an activity in IBM Connections - hedersoft QLite: Leightweight document management system with a web interface, Domino sidebar plugin and webdav interface - hedersoft Workspace: Centrally managed web app and link desktop for users to get to their databases and applications from a browser interface - hedersoft BPM: Activiti BPM (activiti.org) connector to easily worklfow enable IBM Domino databases without any design changes"); + addAttendee(graph, framedGraph, "Henning", "Schmidt", "hschmidt@hedersoft.de", org9); + + Sponsor org10 = createSponsor(framedGraph, "ICON UK", Level.BRONZE, "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/IconUK.gif", + "http://iconuk.org", "ICON UK - The UK ICS User Group running"); + addAttendee(graph, framedGraph, "Tim", "Clark", "iconuk@tc-soft.com", org10); + + Sponsor org11 = createSponsor(framedGraph, "iVision Software", Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/iVision.gif", "http://www.ivissoft.com", ""); + addAttendee(graph, framedGraph, "Mayank", "Singh", "msingh@ivissoft.com", org11); + + Sponsor org12 = createSponsor( + framedGraph, + "Kudos", + Level.GOLD, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Kudos.gif", + "http://www.kudosbadges.com", + "Kudos rewards user adoption, measures performance and increases productivity for IBM Connections. Adding value to organisations in over 30 countries around the world, Kudos is developed by leading Australian collaboration experts and IBM Premier Business Partner; ISW."); + addAttendee(graph, framedGraph, "Adam", "Brown", "abrown@isw.net.au", org12); + + Sponsor org13 = createSponsor( + framedGraph, + "LDC Via", + Level.GOLD, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/LDC-Via.gif", + "http://ldcvia.com", + "Do you need to retire your Domino infrastructure but keep the data? Perhaps you want to extend your Domino data to new horizons, or ease the burden on your Domino servers? Or to explore the new wave of web technologies whilst maintaining your investment in IBM Notes & Domino? LDC Via can help: free your Domino data, making use of a scalable, modern document store with a rich REST API and a variety of template web applications."); + addAttendee(graph, framedGraph, "Matt", "White", "matt@ldcvia.com", org13); + + Sponsor org14 = createSponsor( + framedGraph, + "midpoints GmbH", + Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/MidPoints.gif", + "http://www.midpoints.de", + "midpoints specializes in Enterprise Mobility Consulting and development of mobility solutions based on IBM collaboration software. We're offering solutions for integrating mobile devices, applications and content in a secure and efficient way into and from your internal infrastructure. Our solutions - midpoints mobile.profiler: delivers scalable MDM and MAM based on IBM software. - midpoints traveler.rules: enriches IBM Notes Traveler with important enterprise functions. - midpoints doc.Store: realizes the secure delivery of of documents for mobile devices based on existing IBM infrastructure."); + addAttendee(graph, framedGraph, "Michael", "Ingendoh", "michael.ingendoh@midpoints.de", org14); + + Sponsor org15 = createSponsor( + framedGraph, + "OnTime", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/OnTime.gif", + "http://ontimesuite.com", + "OnTime Group Calendar delivers a real-time overview of the people in your organization by location, availability and business division – anytime, anywhere. Available for IBM Notes, iNotes, Web, IBM Connections and Smart phones."); + addAttendee(graph, framedGraph, "Jeannie", "Overgaard Thanner", "jeo@intravision.dk", org15); + + Sponsor org16 = createSponsor( + framedGraph, + "OpenNTF", + Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/OpenNTF.gif", + "http://openntf.org", + "OpenNTF is the open source community for the IBM Collaboration Solutions portfolio. We are the home of the famous ExtensionLibrary, the Social Business Toolkit, the OpenNTF Domino API and the XPages Toolkit"); + addAttendee(graph, framedGraph, "Christian", "Guedemann", "christian.guedemann@webgate.biz", org16); + + Sponsor org17 = createSponsor(framedGraph, "Opus Neo", Level.BRONZE, "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/OpusNeo.gif", + "http://www.opusneo.com", ""); + addAttendee(graph, framedGraph, "Jan", "Zeuthen", "jfz@opusneo.dk", org17); + + Sponsor org18 = createSponsor( + framedGraph, + "panagenda", + Level.PLATINUM, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Panagenda.gif", + "http://www.panagenda.com", + "Debating between migrating or virtualizing? Unsure if the cloud or consolidating is right for you?  Getting serious about upgrades or modernizing and mobilizing apps?  As leaders in optimizing collaboration landscapes, panagenda helps companies around the world minimize cost, complexity and workload and maximize agility. panagenda solutions are the key to making your strategic decisions a success - from analytics to execution, all across clients, servers and applications, email and social business. With over 7 million licenses in 70 countries, panagenda is your single point of contact for optimizing communication and collaboration!"); + addAttendee(graph, framedGraph, "Florian", "Vogler", "florian.vogler@panagenda.com", org18); + + Sponsor org19 = createSponsor( + framedGraph, + "Pipalia LTD", + Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Pipalia.gif", + "http://www.pipalia.co.uk", + "Pipalia LTD is a company based in London specialising in IBM Notes/Domino and XPages development. We have over 10 years of experience developing in Notes/Domino (version 5 - 9+) and Sage Accounting products. We have recently updated our bespoke end to end system (including accounting integration, back-end order and invocie management, supplier management) for fastkeys.co.uk using XPages, JSF, Bootstrap and Notes Client. We are professional Sage developers and have done projects for many organisations including PwC US and McDonalds."); + addAttendee(graph, framedGraph, "Samir", "Pipalia", "samir@pipalia.co.uk", org19); + + Sponsor org20 = createSponsor( + framedGraph, + "PIXELIXIR", + Level.GOLD, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Pixelixir.gif", + "http://www.pixelixir.com", + "Known for his expertise since 15 years as a renowned technology advisor and leading system integrator, PIXELIXIR with his team of ICT innovators & certified specialists work closely with a lot of companies of all sizes to provide innovative, efficient solutions, and deliver measurable business added-value in the field of Unified Messaging, Social Business, Shared Environnements, Security, Cloud, eCommerce, Mobile Apps, Digital Marketing ..."); + addAttendee(graph, framedGraph, "Thibault", "Anderlin", "ta@pixelixir.com", org20); + + Sponsor org21 = createSponsor( + framedGraph, + "Red Pill Development", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Redpill.gif", + "http://redpilldevelopment.com", + "When it comes to the future of your IBM Notes applications, you have a choice. You can take the blue pill and accept the status quo. Or, take the Red Pill and see your Notes applications come to life on your desktop and mobile devices, in a fully responsive, CSS3- and HTML5-compliant design. We get you there in less time than you think, at a price that makes sense, and without the risks of migration and retooling. What’s more, choosing the Red Pill means an immediate, measurable benefit for every user across your enterprise, and an ongoing process for progressive modernization of all your apps. Want to learn more about asymmetric modernization services for your portfolio of Notes applications before we meet at the conference? Visit www.redpilldevelopment.com, or contact us at info@redpilldevelopment.com."); + addAttendee(graph, framedGraph, "Peter", "Presnell", "peter@redpilldevelopment.com", org21); + + Sponsor org22 = createSponsor( + framedGraph, + "Silverside", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Silverside.gif", + "", + "Take responsibility and speak up, that’s what we do as well. We are convinced that the biggest challenge for the next 5 years is the adoption of software in our market. By taking responsibility for the adoption of Microsoft SharePoint and IBM Software we will be the best valued partner in our market. The consultants of Silverside build bridges between business and IT and work focussed on improving efficiency, productivity and ROI with customers. We strive for an optimal mix of collaboration of people, business goals and technological best of breed platforms."); + addAttendee(graph, framedGraph, "Roland", "Driesen", "r.driesen@silverside.nl", org22); + + Sponsor org23 = createSponsor(framedGraph, "Social Connections", Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/SocialConnections.gif", "http://socialconnections.info", + "April 16-17, 2015 IBM Innovation Centre - 1 Rogers Street - Cambridge, MA 02142"); + addAttendee(graph, framedGraph, "Stuart", "McIntyre", "info@socialconnections.info", org23); + + Sponsor org24 = createSponsor( + framedGraph, + "Teamstudio, Inc.", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Teamstudio.gif", + "http://teamstudio.com", + "Whether you want to build a mobile app yourself or have us build one for you, Teamstudio enables your workforce to be productive anytime, anywhere, with uninterrupted offline access to mobile applications. And with innovative tools to manage Notes and Domino, working with Teamstudio is the smartest move you’ll make. Learn more at teamstudio.com"); + addAttendee(graph, framedGraph, "Taline", "Badrikian", "taline_badrikian@teamstudio.com", org24); + + Sponsor org25 = createSponsor( + framedGraph, + "TIMETOACT GROUP", + Level.GOLD, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/TimeToActGroup.gif", + "http://www.timetoact-group.com", + "TIMETOACT is a Premier IBM Business Partner with major investment into assets, products and services for IBM Connections. TIMETOACT products for IBM Connections include: - CAT - Connections Administration Toolkit Simplify and Improve IBM Connections Administration and Content Management - UAM - User Access Manager Manage External (Guest) Users for IBM Connections, Internal Users “Terms of Use” Acceptance, Passwords etc. - XCC - Web Content Management & Custom Apps Extension Integrate Internal Communications and Custom Applications into IBM Connections With about about 200 employees, TIMETOACT GROUP is one of the largest IBM Software Services providers in DACH. TIMETOACT GROUP is located in several locations in Germany and Switzerland."); + addAttendee(graph, framedGraph, "Monika", "Bach", "monika.bach@timetoact.de", org25); + + Sponsor org26 = createSponsor( + framedGraph, + "TLCC", + Level.BRONZE, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/TLCC.gif", + "http://www.tlcc.com", + "TLCC is the leading provider of self-paced training courses for Domino developers and administrators including a complete line of XPages courses. Visit tlcc.com to try a FREE course."); + addAttendee(graph, framedGraph, "Howard", "Greenberg", "howardg@tlcc.com", org26); + + Sponsor org27 = createSponsor( + framedGraph, + "Trilog - Soluster", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Soluster.gif", + "http://www.project4Connections.com", + "Project Management Made Social: Planning is not enough! Empower your project teams with powerful social collaboration tools to achieve common goals. Use the Power of IBM Connections: Building upon the IBM Connections platform, ProjExec provides a comprehensive PM solution for leveraging all of your favorite social media platform. A Real Alternative to MS-Project: ProjExec Social Gantt delivers all functions expected by project managers, including an incredible, bi-directional integration with Microsoft Project."); + addAttendee(graph, framedGraph, "Christophe", "Borlat", "cborlat@soluster.com", org27); + + Sponsor org28 = createSponsor( + framedGraph, + "VitalSigns", + Level.SILVER, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/VitalSigns.gif", + "http://www.rprvitalsigns.com", + "VitalSigns helps Customers be more pro-active and agile towards IT Operational Management. Improving the end user experience on the Business side as well as helping Customers to save spending in IT is VitalSigns key mission."); + addAttendee(graph, framedGraph, "Carwin", "Heierman", "carwin@rprvitalsigns.com", org28); + + Sponsor org29 = createSponsor( + framedGraph, + "We4IT", + Level.GOLD, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/We4IT.gif", + "http://www.we4it.com", + "We4IT is an IBM Premier Business Partner and provider of managed services and products relating to IBM Collaboration Solutions (ICS). We help clients by managing or even completely outsourcing their ICS environment and transforming their IBM Notes applications in a web and mobile strategy. To complete our line-up, we offer Software-as-a-Service (SaaS) using either a public or private cloud."); + addAttendee(graph, framedGraph, "Stefan", "Sucker", "stefan.sucker@we4it.com", org29); + + Sponsor org30 = createSponsor( + framedGraph, + "Ytria", + Level.PLATINUM, + "http://www.engage.ug/engage.nsf/Pages/Sponsors/$File/Ytria.gif", + "http://www.ytria.com", + "Enhance your administration efficiency and save development time on your IBM Notes and Domino platform with EZ Suite tools. Ytria solutions help you find problems before they manifest and fix them in no time. Perform countless tasks, otherwise impossible to achieve, with global-analysis capabilities and mass-modification features. Stop by our booth and see how you can access and modify anything you need to improve productivity, accuracy and response time all at once!"); + addAttendee(graph, framedGraph, "Sonia", "Bounardjian", "sbounardjian@ytria.com", org30); + + framedGraph.commit(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public Sponsor createSponsor(FramedTransactionalGraph framedGraph, String name, Level level, String photoUrl, String webUrl, + String profile) { + Sponsor org = null; + Group check = framedGraph.getVertex(name, Group.class); + if (null != check) { + Vertex vert = check.asVertex(); + vert.setProperty("form", "Sponsor"); + framedGraph.commit(); + org = framedGraph.getVertex(name, Sponsor.class); + } else { + org = framedGraph.addVertex(name, Sponsor.class); + org.setName(name); + org.setType(Group.Type.COMPANY); + } + org.setLevel(level); + org.setPhotoUrl(photoUrl); + org.setUrl(webUrl); + org.setProfile(profile); + return org; + } + + public void addAttendee(ConferenceGraph graph, FramedTransactionalGraph framedGraph, String firstName, String lastName, String email, + Sponsor org) { + Attendee att = graph.getAttendee(firstName + " " + lastName); + if (null == att) { + att = framedGraph.addVertex(null, Attendee.class); + att.setFirstName(firstName); + att.setLastName(lastName); + } + att.setEmail(email); + org.addMember(att); + org.addContactFor(att); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new DataInitializerSponsorsForEngage(), TestRunnerUtil.NATIVE_SESSION); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Event.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Event.java new file mode 100644 index 0000000..3ce95e8 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Event.java @@ -0,0 +1,140 @@ +package org.openntf.conference.graph; + +import org.openntf.conference.graph.Attendee.Attending; +import org.openntf.conference.graph.Attendee.PlansToAttend; +import org.openntf.conference.graph.Invite.InvitationFor; +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.DEdgeFrame; +import org.openntf.domino.graph2.builtin.social.Commentable; +import org.openntf.domino.graph2.builtin.social.Likeable; +import org.openntf.domino.graph2.builtin.social.Rateable; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.InVertex; +import com.tinkerpop.frames.OutVertex; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Event") +public abstract interface Event extends Commentable, Likeable, Rateable { + @TypeValue(HappeningOn.LABEL) + public static interface HappeningOn extends DEdgeFrame { + public static final String LABEL = "HappeningOn"; + + @InVertex + public TimeSlot getTimeslot(); + + @OutVertex + public Event getEvent(); + } + + @TypeValue(HappeningAt.LABEL) + public static interface HappeningAt extends DEdgeFrame { + public static final String LABEL = "HappeningAt"; + + @InVertex + public Location getLocation(); + + @OutVertex + public Event getEvent(); + } + + public static enum Status { + DRAFT, PROPOSED, CONFIRMED, CANCELLED; + } + + @TypedProperty("Title") + public String getTitle(); + + @TypedProperty("Title") + public void setTitle(String title); + + @TypedProperty("Description") + public String getDescription(); + + @TypedProperty("Description") + public void setDescription(String description); + + @TypedProperty("Status") + public Status getStatus(); + + @TypedProperty("Status") + public void setStatus(Status status); + + @AdjacencyUnique(label = PlansToAttend.LABEL, direction = Direction.IN) + public Iterable getPlansToAttendAttendees(); + + @AdjacencyUnique(label = PlansToAttend.LABEL, direction = Direction.IN) + public PlansToAttend addPlansToAttend(Attendee attendee); + + @AdjacencyUnique(label = PlansToAttend.LABEL, direction = Direction.IN) + public void removePlansToAttend(Attendee attendee); + + @IncidenceUnique(label = PlansToAttend.LABEL, direction = Direction.IN) + public Iterable getPlansToAttends(); + + @IncidenceUnique(label = PlansToAttend.LABEL, direction = Direction.IN) + public void removePlansToAttend(PlansToAttend plansToAttend); + + @AdjacencyUnique(label = Attending.LABEL, direction = Direction.IN) + public Iterable getAttendingAttendees(); + + @AdjacencyUnique(label = Attending.LABEL, direction = Direction.IN) + public Attending addAttendingAttendee(Attendee attendee); + + @AdjacencyUnique(label = Attending.LABEL, direction = Direction.IN) + public void removeAttendingAttendee(Attendee attendee); + + @IncidenceUnique(label = Attending.LABEL, direction = Direction.IN) + public Iterable getAttendings(); + + @IncidenceUnique(label = Attending.LABEL, direction = Direction.IN) + public void removeAttending(Attending attending); + + @AdjacencyUnique(label = HappeningOn.LABEL) + public Iterable getTimes(); + + @AdjacencyUnique(label = HappeningOn.LABEL) + public HappeningOn addTime(TimeSlot time); + + @AdjacencyUnique(label = HappeningOn.LABEL) + public void removingTime(TimeSlot time); + + @IncidenceUnique(label = HappeningOn.LABEL) + public Iterable getHappeningOns(); + + @IncidenceUnique(label = HappeningOn.LABEL) + public void removingHappeningOn(HappeningOn happeningOn); + + @AdjacencyUnique(label = HappeningAt.LABEL) + public Iterable getLocations(); + + @AdjacencyUnique(label = HappeningAt.LABEL) + public HappeningAt addLocation(Location location); + + @AdjacencyUnique(label = HappeningAt.LABEL) + public void removingLocation(Location location); + + @IncidenceUnique(label = HappeningAt.LABEL) + public Iterable getHappeningAts(); + + @IncidenceUnique(label = HappeningAt.LABEL) + public void removingHappeningAt(HappeningAt happeningAt); + + @AdjacencyUnique(label = InvitationFor.LABEL) + public Iterable getInvites(); + + @AdjacencyUnique(label = InvitationFor.LABEL) + public InvitationFor addInvite(Invite invite); + + @AdjacencyUnique(label = InvitationFor.LABEL) + public void removeInvite(Invite invite); + + @IncidenceUnique(label = InvitationFor.LABEL) + public InvitationFor getInvitationFors(); + + @IncidenceUnique(label = InvitationFor.LABEL) + public void removeInvitationFor(InvitationFor invitationFor); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Group.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Group.java new file mode 100644 index 0000000..2ad0bdf --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Group.java @@ -0,0 +1,46 @@ +package org.openntf.conference.graph; + +import org.openntf.conference.graph.Attendee.MemberOf; +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.social.Commentable; +import org.openntf.domino.graph2.builtin.social.Likeable; +import org.openntf.domino.graph2.builtin.social.Rateable; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Group") +public interface Group extends Commentable, Likeable, Rateable { + public static enum Type { + OPEN, COMPANY, SOCIAL, PROGRAM, PRIVATE + } + + @TypedProperty("Name") + public String getName(); + + @TypedProperty("Name") + public void setName(String name); + + @TypedProperty("Type") + public Type getType(); + + @TypedProperty("Type") + public void setType(Type type); + + @AdjacencyUnique(label = MemberOf.LABEL, direction = Direction.IN) + public Iterable getMembers(); + + @AdjacencyUnique(label = MemberOf.LABEL, direction = Direction.IN) + public MemberOf addMember(Attendee attendee); + + @AdjacencyUnique(label = MemberOf.LABEL, direction = Direction.IN) + public void removeMember(Attendee attendee); + + @IncidenceUnique(label = MemberOf.LABEL, direction = Direction.IN) + public Iterable getMemberOfs(); + + @IncidenceUnique(label = MemberOf.LABEL, direction = Direction.IN) + public void removeMemberOf(MemberOf memberOf); +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Invite.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Invite.java new file mode 100644 index 0000000..3fbfba7 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Invite.java @@ -0,0 +1,120 @@ +package org.openntf.conference.graph; + +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.DEdgeFrame; +import org.openntf.domino.graph2.builtin.DVertexFrame; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.InVertex; +import com.tinkerpop.frames.OutVertex; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Invite") +public interface Invite extends DVertexFrame { + @TypeValue(Invites.LABEL) + public static interface Invites extends DEdgeFrame { + public static final String LABEL = "Invites"; + + public static enum Status { + DRAFT, SENT, WITHDRAWN; + } + + @InVertex + public Attendee getInviter(); + + @OutVertex + public Invite getInvite(); + + @TypedProperty("Status") + public Status getStatus(); + + @TypedProperty("Status") + public void setStatus(Status status); + } + + @TypeValue(InvitedTo.LABEL) + public static interface InvitedTo extends DEdgeFrame { + public static final String LABEL = "InvitedTo"; + + public static enum Status { + UNREAD, OPEN, TENTATIVE, COMMITTED, DECLINED; + } + + @OutVertex + public Attendee getInvitee(); + + @InVertex + public Invite getInvite(); + + @TypedProperty("Status") + public Status getStatus(); + + @TypedProperty("Status") + public void setStatus(Status status); + } + + @TypeValue(InvitationFor.LABEL) + public static interface InvitationFor extends DEdgeFrame { + public static final String LABEL = "InvitationFor"; + + @InVertex + public Event getEvent(); + + @OutVertex + public Invite getInvite(); + } + + @TypedProperty("Message") + public String getMessage(); + + @TypedProperty("Message") + public void setMessage(String message); + + @AdjacencyUnique(label = Invites.LABEL, direction = Direction.IN) + public Attendee getInvitingAttendee(); + + @AdjacencyUnique(label = Invites.LABEL, direction = Direction.IN) + public Invites addInvites(Attendee inviter); + + @AdjacencyUnique(label = Invites.LABEL, direction = Direction.IN) + public void removeInvites(Attendee inviter); + + @IncidenceUnique(label = Invites.LABEL, direction = Direction.IN) + public Invites getInvites(); + + @IncidenceUnique(label = Invites.LABEL, direction = Direction.IN) + public void removeInvites(Invites invites); + + @AdjacencyUnique(label = InvitedTo.LABEL) + public Iterable getInvitedToAttendees(); + + @AdjacencyUnique(label = InvitedTo.LABEL) + public Invites addInvitedTo(Attendee invitee); + + @AdjacencyUnique(label = InvitedTo.LABEL) + public void removeInvitedTo(Attendee invitee); + + @IncidenceUnique(label = InvitedTo.LABEL) + public Iterable getInvitedTos(); + + @IncidenceUnique(label = InvitedTo.LABEL) + public void removeInvitedTo(InvitedTo invitedTo); + + @AdjacencyUnique(label = InvitationFor.LABEL, direction = Direction.IN) + public Event getEvent(); + + @AdjacencyUnique(label = InvitationFor.LABEL, direction = Direction.IN) + public InvitationFor addEvent(Event event); + + @AdjacencyUnique(label = InvitationFor.LABEL, direction = Direction.IN) + public void removeEvent(Event event); + + @IncidenceUnique(label = InvitationFor.LABEL, direction = Direction.IN) + public InvitationFor getInvitationFors(); + + @IncidenceUnique(label = InvitationFor.LABEL, direction = Direction.IN) + public void removeInvitationFor(InvitationFor invitationFor); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Location.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Location.java new file mode 100644 index 0000000..29ab3e9 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Location.java @@ -0,0 +1,91 @@ +package org.openntf.conference.graph; + +import java.util.Date; + +import org.openntf.conference.graph.Event.HappeningAt; +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.social.Commentable; +import org.openntf.domino.graph2.builtin.social.Likeable; +import org.openntf.domino.graph2.builtin.social.Rateable; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Location") +public interface Location extends Commentable, Likeable, Rateable { + public static enum Features { + RESTAURANT, REFRESHMENTS, BAR, OUTDOOR; + } + + @TypedProperty("Name") + public String getName(); + + @TypedProperty("Name") + public void setName(String name); + + @TypedProperty("Latitude") + public Double getLatitude(); + + @TypedProperty("Latitude") + public void setLatitude(Double latitude); + + @TypedProperty("Longitude") + public Double getLongitude(); + + @TypedProperty("Longitude") + public void setLongitude(Double longitude); + + @TypedProperty("Mapurl") + public String getMapUrl(); + + @TypedProperty("Mapurl") + public void setMapUrl(String mapUrl); + + @TypedProperty("Floor") + public String getFloor(); + + @TypedProperty("Floor") + public void setFloor(String floor); + + @TypedProperty("Address") + public String getAddress(); + + @TypedProperty("Address") + public void setAddress(String address); + + @TypedProperty("OpenTime") + public Date getOpenTime(); + + @TypedProperty("OpenTime") + public void setOpenTime(Date time); + + @TypedProperty("CloseTime") + public Date getCloseTime(); + + @TypedProperty("CloseTime") + public void setCloseTime(Date time); + + @TypedProperty("Features") + public Features[] getFeatures(); + + @TypedProperty("Features") + public void setFeatures(Features[] features); + + @AdjacencyUnique(label = HappeningAt.LABEL, direction = Direction.IN) + public Iterable getEvents(); + + @AdjacencyUnique(label = HappeningAt.LABEL, direction = Direction.IN) + public HappeningAt addEvent(Event event); + + @AdjacencyUnique(label = HappeningAt.LABEL, direction = Direction.IN) + public void removingEvent(Event event); + + @IncidenceUnique(label = HappeningAt.LABEL, direction = Direction.IN) + public Iterable getHappeningAts(); + + @IncidenceUnique(label = HappeningAt.LABEL, direction = Direction.IN) + public void removingHappeningAt(HappeningAt happeningAt); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Meeting.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Meeting.java new file mode 100644 index 0000000..e2f8f9b --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Meeting.java @@ -0,0 +1,8 @@ +package org.openntf.conference.graph; + +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Meeting") +public interface Meeting extends Event { + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Presentation.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Presentation.java new file mode 100644 index 0000000..73e54e2 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Presentation.java @@ -0,0 +1,69 @@ +package org.openntf.conference.graph; + +import org.openntf.conference.graph.Track.Includes; +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.DEdgeFrame; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.InVertex; +import com.tinkerpop.frames.OutVertex; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Presentation") +public interface Presentation extends Event { + @TypeValue(PresentedBy.LABEL) + public static interface PresentedBy extends DEdgeFrame { + public static final String LABEL = "PresentedBy"; + + @OutVertex + public Attendee getPresenter(); + + @InVertex + public Presentation getSession(); + } + + @TypedProperty("SessionID") + public String getSessionId(); + + @TypedProperty("SessionID") + public void setSessionId(String sessionid); + + @TypedProperty("Level") + public String getLevel(); + + @TypedProperty("Level") + public void setLevel(String level); + + @AdjacencyUnique(label = PresentedBy.LABEL, direction = Direction.IN) + public Iterable getPresentingAttendees(); + + @AdjacencyUnique(label = PresentedBy.LABEL, direction = Direction.IN) + public PresentedBy addPresentedBy(Attendee presenter); + + @AdjacencyUnique(label = PresentedBy.LABEL, direction = Direction.IN) + public void removePresentedBy(Attendee presenter); + + @IncidenceUnique(label = PresentedBy.LABEL, direction = Direction.IN) + public Iterable getPresentings(); + + @IncidenceUnique(label = PresentedBy.LABEL, direction = Direction.IN) + public void removePresentedBy(PresentedBy presentedBy); + + @AdjacencyUnique(label = Includes.LABEL) + public Iterable getIncludedInTracks(); + + @AdjacencyUnique(label = Includes.LABEL) + public Includes addIncludedIn(Track track); + + @AdjacencyUnique(label = Includes.LABEL) + public void removeIncludedIn(Track track); + + @IncidenceUnique(label = Includes.LABEL) + public Iterable getIncludedIn(); + + @IncidenceUnique(label = Includes.LABEL) + public void removeIncludedIn(Includes includes); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Social.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Social.java new file mode 100644 index 0000000..a091c1e --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Social.java @@ -0,0 +1,18 @@ +package org.openntf.conference.graph; + +import org.openntf.domino.graph2.annotations.TypedProperty; + +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Social") +public interface Social extends Event { + public static enum Features { + REFRESHMENTS, OPENBAR, MUSIC, CODING, DEMO + } + + @TypedProperty("Features") + public Features[] getFeatures(); + + @TypedProperty("Features") + public void setFeatures(Features[] features); +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Sponsor.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Sponsor.java new file mode 100644 index 0000000..c092058 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Sponsor.java @@ -0,0 +1,76 @@ +package org.openntf.conference.graph; + +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.DEdgeFrame; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.InVertex; +import com.tinkerpop.frames.OutVertex; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Sponsor") +public abstract interface Sponsor extends Group { + + public static enum Level { + STRATEGIC(0), PLATINUM(1), GOLD(2), SILVER(3), BRONZE(4); + + private final int value_; + + private Level(final int level) { + value_ = level; + } + + public int getValue() { + return value_; + } + } + + @TypeValue(ContactFor.LABEL) + public static interface ContactFor extends DEdgeFrame { + public static final String LABEL = "ContactFor"; + + @OutVertex + public Attendee getContacts(); + + @InVertex + public Sponsor getContactsFor(); + } + + // How do we always set the type to COMPANY? Do we need a FrameInitializer + // for this? + + @TypedProperty("Url") + public String getUrl(); + + @TypedProperty("Url") + public void setUrl(String url); + + @TypedProperty("PhotoUrl") + public String getPhotoUrl(); + + @TypedProperty("PhotoUrl") + public void setPhotoUrl(String photoUrl); + + @TypedProperty("Profile") + public String getProfile(); + + @TypedProperty("Profile") + public void setProfile(String profile); + + @TypedProperty("Level") + public Level getLevel(); + + @TypedProperty("Level") + public void setLevel(Level level); + + @AdjacencyUnique(label = ContactFor.LABEL, direction = Direction.IN) + public Iterable getContactAttendees(); + + @AdjacencyUnique(label = ContactFor.LABEL, direction = Direction.IN) + public ContactFor addContactFor(Attendee contact); + + @AdjacencyUnique(label = ContactFor.LABEL, direction = Direction.IN) + public void removeContactFor(Attendee contact); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/TimeSlot.java b/samples/ConferenceApp/src/org/openntf/conference/graph/TimeSlot.java new file mode 100644 index 0000000..8f2ee79 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/TimeSlot.java @@ -0,0 +1,90 @@ +package org.openntf.conference.graph; + +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.openntf.conference.graph.Event.HappeningOn; +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.DVertexFrame; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.modules.javahandler.JavaHandler; +import com.tinkerpop.frames.modules.javahandler.JavaHandlerClass; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@JavaHandlerClass(TimeSlot.TimeSlotImpl.class) +@TypeValue("TimeSlot") +public interface TimeSlot extends DVertexFrame { + public abstract static class TimeSlotImpl implements TimeSlot { + @Override + @JavaHandler + public Integer getDuration() { + Integer result = Integer.valueOf(0); + try { + Calendar start = getStartTime(); + Calendar end = getEndTime(); + long msDifference = end.getTime().getTime() - start.getTime().getTime(); + result = Integer.valueOf(Long.valueOf(msDifference / 60000).intValue()); + } catch (Throwable t) { + // TODO what? + } + return result; + } + + @Override + @JavaHandler + public String getDay() { + String result = ""; + try { + Calendar start = getStartTime(); + SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd MMM"); + result = DATE_FORMAT.format(start.getTime()); + } catch (Exception e) { + // TODO: handle exception + } + return result; + } + } + + @TypedProperty("Starttime") + public Calendar getStartTime(); + + @TypedProperty("Starttime") + public void setStartTime(Calendar startTime); + + @TypedProperty("Endtime") + public Calendar getEndTime(); + + @TypedProperty("Endtime") + public void setEndTime(Calendar endTime); + + @TypedProperty("Official") + public int getOfficial(); + + @TypedProperty("Official") + public void setOfficial(int official); + + @JavaHandler + public Integer getDuration(); // in minutes + + @JavaHandler + public String getDay(); // in dd MMM format + + @AdjacencyUnique(label = HappeningOn.LABEL, direction = Direction.IN) + public Iterable getEvents(); + + @AdjacencyUnique(label = HappeningOn.LABEL, direction = Direction.IN) + public HappeningOn addEvent(Event event); + + @AdjacencyUnique(label = HappeningOn.LABEL, direction = Direction.IN) + public void removingEvent(Event event); + + @IncidenceUnique(label = HappeningOn.LABEL, direction = Direction.IN) + public Iterable getHappeningOns(); + + @IncidenceUnique(label = HappeningOn.LABEL, direction = Direction.IN) + public void removingHappeningOn(HappeningOn happeningOn); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/Track.java b/samples/ConferenceApp/src/org/openntf/conference/graph/Track.java new file mode 100644 index 0000000..7873d04 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/Track.java @@ -0,0 +1,54 @@ +package org.openntf.conference.graph; + +import org.openntf.domino.graph2.annotations.AdjacencyUnique; +import org.openntf.domino.graph2.annotations.IncidenceUnique; +import org.openntf.domino.graph2.annotations.TypedProperty; +import org.openntf.domino.graph2.builtin.DEdgeFrame; +import org.openntf.domino.graph2.builtin.DVertexFrame; + +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.frames.InVertex; +import com.tinkerpop.frames.OutVertex; +import com.tinkerpop.frames.modules.typedgraph.TypeValue; + +@TypeValue("Track") +public interface Track extends DVertexFrame { + @TypeValue(Includes.LABEL) + public static interface Includes extends DEdgeFrame { + public static final String LABEL = "Includes"; + + @InVertex + public Track getTrack(); + + @OutVertex + public Presentation getSession(); + } + + @TypedProperty("Title") + public String getTitle(); + + @TypedProperty("Title") + public void setTitle(String title); + + @TypedProperty("Description") + public String getDescription(); + + @TypedProperty("Description") + public void setDescription(String description); + + @AdjacencyUnique(label = Includes.LABEL, direction = Direction.IN) + public Iterable getIncludesSessions(); + + @AdjacencyUnique(label = Includes.LABEL, direction = Direction.IN) + public Includes addIncludesSession(Presentation session); + + @AdjacencyUnique(label = Includes.LABEL, direction = Direction.IN) + public void removeIncludesSession(Presentation session); + + @IncidenceUnique(label = Includes.LABEL, direction = Direction.IN) + public Iterable getIncludes(); + + @IncidenceUnique(label = Includes.LABEL, direction = Direction.IN) + public void removeIncludes(Includes includes); + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/AttendeeTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/AttendeeTester.java new file mode 100644 index 0000000..8fbea92 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/AttendeeTester.java @@ -0,0 +1,84 @@ +package org.openntf.conference.graph.examples; + +import org.openntf.domino.big.NoteCoordinate; +import org.openntf.domino.graph2.DEdge; +import org.openntf.domino.graph2.DVertex; +import org.openntf.domino.junit.TestRunnerUtil; + +import java.util.List; +import java.util.Map; + +import javolution.util.FastSet; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.conference.graph.Presentation; +import org.openntf.conferenceapp.service.ConferenceGraphFactory; +import org.openntf.conferenceapp.service.ConferenceManager; +import org.openntf.conferenceapp.service.EventFactory; + +import com.google.common.collect.Lists; +import com.tinkerpop.blueprints.Direction; +import com.tinkerpop.blueprints.Graph; +import com.tinkerpop.frames.FramedGraph; +import com.tinkerpop.frames.FramedTransactionalGraph; + +public class AttendeeTester implements Runnable { + private long marktime; + + public AttendeeTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + FramedTransactionalGraph graph = (FramedTransactionalGraph) ConferenceGraphFactory.getGraph("engage"); + Iterable atts = (Iterable) graph.getVertices("Twitter", "paulswithers", Attendee.class); + Attendee paulwithers = atts.iterator().next(); + Map props = paulwithers.asMap(); + System.out.println("Outputting properties for Paul Withers"); + for (CharSequence key : props.keySet()) { + System.out.println(key + " - " + props.get(key)); + } + System.out.println("***************"); + DVertex vert = (DVertex) paulwithers.asVertex(); + NoteCoordinate note = (NoteCoordinate) vert.getId(); + System.out.println("Current Id = " + note.toString()); + + ConferenceGraph baseGraph = ConferenceGraphFactory.getConference(ConferenceGraphFactory.ENGAGE_KEY); + Attendee me = baseGraph.getAttendee("paulswithers",false); + if (null != me) { + System.out.println("Found " + me.getFirstName() + " " + me.getLastName()); + } else { + System.out.println("Couldn't find me"); + } + + paulwithers.setEmail("pwithers@intec.co.uk"); + graph.commit(); + +// System.out.println("Changing key to pwithers@intec.co.uk"); +// vert.setProperty("$$Key", "pwithers@intec.co.uk"); +// vert.commit(); +// System.out.println("Changed key to pwithers@intec.co.uk"); +// graph.getVertex("pwithers@intec.co.uk", Attendee.class); + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new AttendeeTester(), TestRunnerUtil.NATIVE_SESSION); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/EventTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/EventTester.java new file mode 100644 index 0000000..d13d633 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/EventTester.java @@ -0,0 +1,69 @@ +package org.openntf.conference.graph.examples; + +import java.util.List; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Presentation; +import org.openntf.conferenceapp.service.AttendeeFactory; +import org.openntf.conferenceapp.service.EventFactory; +import org.openntf.domino.junit.TestRunnerUtil; + +import com.google.common.collect.Lists; + +public class EventTester implements Runnable { + private long marktime; + + public EventTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + List pres = Lists.newArrayList(EventFactory.getPresentationsSortedByProperty("Title")); + System.out.println("Listing Presentations by Title..."); + for (Presentation p : pres) { + System.out.println(p.getSessionId() + " - " + p.getTitle()); + } + System.out.println("******************"); + + pres = Lists.newArrayList(EventFactory.getPresentationsSortedByProperty("SessionID")); + System.out.println("Listing Presentations by Session ID..."); + for (Presentation p : pres) { + System.out.println(p.getSessionId() + " - " + p.getTitle()); + } + System.out.println("******************"); + + System.out.println("Outputting speakers for tracks..."); + List speakers = Lists.newArrayList(AttendeeFactory.getSpeakers("")); + for (Attendee speaker : speakers) { + System.out.println(speaker.getFirstName() + " " + speaker.getLastName() + " - " + speaker.getTwitterId()); + } + System.out.println("******************"); + + System.out.println("Outputting speakers for tracks from Gremlin..."); + List speakersGremlin = Lists.newArrayList(EventFactory.getSpeakers("Dev")); + for (Attendee speaker : speakersGremlin) { + System.out.println(speaker.getFirstName() + " " + speaker.getLastName() + " - " + speaker.getTwitterId()); + } + System.out.println("******************"); + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new EventTester(), TestRunnerUtil.NATIVE_SESSION); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/GraphExamples.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/GraphExamples.java new file mode 100644 index 0000000..f9388a7 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/GraphExamples.java @@ -0,0 +1,35 @@ +package org.openntf.conference.graph.examples; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.domino.Session; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +import com.tinkerpop.frames.FramedGraph; + +public class GraphExamples { + private ConferenceGraph theConference_; + + public GraphExamples() { + // TODO Auto-generated constructor stub + } + + public ConferenceGraph getConference() { + if (theConference_ == null) { + theConference_ = new ConferenceGraph(); + } + return theConference_; + } + + public FramedGraph getGraph() { + return getConference().getFramedGraph(); + } + + public Attendee getMe() { + Session session = Factory.getSession(SessionType.CURRENT); + String myName = session.getEffectiveUserName(); + return getConference().getAttendee(myName, true); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/LocationTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/LocationTester.java new file mode 100644 index 0000000..9d20b2f --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/LocationTester.java @@ -0,0 +1,62 @@ +package org.openntf.conference.graph.examples; + +import java.util.List; + +import javolution.util.FastSet; + +import org.openntf.conference.graph.Location; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.conferenceapp.service.EventFactory; +import org.openntf.conferenceapp.service.LocationFactory; +import org.openntf.domino.junit.TestRunnerUtil; + +public class LocationTester implements Runnable { + private long marktime; + + public LocationTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + System.out.println("Getting Locations..."); + List locs = LocationFactory.getLocationsSortedByProperty(""); + Location location = null; + for (Location loc : locs) { + if (null == location) { + location = loc; + } + System.out.println(loc.getName()); + } + System.out.println("************************"); + + System.out.println("Getting presentations for " + location.getName()); + FastSet presentations = EventFactory.getPresentationsByLocation(location); + for (Presentation pres : presentations) { + TimeSlot ts = pres.getTimes().iterator().next(); + System.out.println(pres.getTitle() + ": " + ts.getStartTime().getTime() + "-" + ts.getEndTime().getTime()); + } + System.out.println("************************"); + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new LocationTester(), TestRunnerUtil.NATIVE_SESSION); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/MiscTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/MiscTester.java new file mode 100644 index 0000000..ef509f7 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/MiscTester.java @@ -0,0 +1,90 @@ +package org.openntf.conference.graph.examples; + +import javolution.util.FastSet; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.conference.graph.Event; +import org.openntf.conference.graph.Presentation; +import org.openntf.conferenceapp.service.ConferenceGraphFactory; +import org.openntf.domino.graph2.builtin.social.Comment; +import org.openntf.domino.graph2.builtin.social.Rates; +import org.openntf.domino.junit.TestRunnerUtil; + +import com.google.common.collect.Lists; + +public class MiscTester implements Runnable { + private long marktime; + + public MiscTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + ConferenceGraph graph = ConferenceGraphFactory.getConference(ConferenceGraphFactory.ENGAGE_KEY); + Attendee paul = graph.getAttendee("paulswithers"); + System.out.println(paul.getEmail()); + Iterable evts = paul.getAttendingEvents(); + FastSet presentations = new FastSet(); + for (Event evt : evts) { + if (evt instanceof Presentation) { + presentations.add((Presentation) evt); + } + } + System.out.println("Paul is attending " + presentations.size() + " Sessions"); + evts = paul.getPresentingEvents(); + presentations = new FastSet(); + for (Event evt : evts) { + if (evt instanceof Presentation) { + presentations.add((Presentation) evt); + } + } + System.out.println("Paul is presenting " + presentations.size() + " Sessions"); + Presentation pres = presentations.iterator().next(); + Comment comm = graph.getFramedGraph().addVertex(null, Comment.class); + comm.setBody("This is a test comment"); + paul.addComment(comm); + pres.addComment(comm); + paul.addLikes(comm); + paul.addLikes(pres); + Rates rate = paul.addRates(pres); + rate.setRating(5); + Rates rate2 = paul.addRates(pres); + rate2.setRating(2); + + System.out.println("Comments by Paul: " + Lists.newArrayList(paul.getComments()).size()); + for (Comment testComm : paul.getComments()) { + System.out.println(testComm.getBody()); + } + System.out.println("Likes by Paul: " + Lists.newArrayList(paul.getLikes()).size()); + System.out.println("Comments on Pres: " + Lists.newArrayList(pres.getComments()).size()); + System.out.println("Likes on Pres: " + Lists.newArrayList(pres.getLikedBy()).size()); + System.out.println("Rates on Pres: " + Lists.newArrayList(pres.getRates()).size()); + for (Rates r : Lists.newArrayList(pres.getRates())) { + System.out.println("Rating - " + r.asEdge().getId() + " - " + r.getRating()); + } + System.out.println("Rating by Paul: " + pres.getRaterRating(paul)); + System.out.println("Average: " + pres.getAverageRating()); + + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new MiscTester(), TestRunnerUtil.NATIVE_SESSION); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SessionsByTimeslot.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SessionsByTimeslot.java new file mode 100644 index 0000000..9056846 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SessionsByTimeslot.java @@ -0,0 +1,70 @@ +package org.openntf.conference.graph.examples; + +import java.text.SimpleDateFormat; +import java.util.List; + +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.conference.graph.Event; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.domino.junit.TestRunnerUtil; + +import com.google.common.collect.Ordering; + +public class SessionsByTimeslot implements Runnable { + private long marktime; + private SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd/MM HH:mm"); + + public SessionsByTimeslot() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + timelog("Beginning Sessions By TimeSlot..."); + ConferenceGraph graph = new ConferenceGraph(); + + Ordering byStart = new Ordering() { + + @Override + public int compare(final TimeSlot t1, final TimeSlot t2) { + return t1.getStartTime().compareTo(t2.getStartTime()); + } + }; + + Iterable times = graph.getTimeSlots(); + List timesSorted = byStart.sortedCopy(times); + for (TimeSlot ts : timesSorted) { + System.out.println("Sessions running from " + DATE_FORMAT.format(ts.getStartTime().getTime()) + " to " + + DATE_FORMAT.format(ts.getEndTime().getTime())); + Iterable presentations = ts.getEvents(); + for (Event evt : presentations) { + if (evt instanceof Presentation) { + Presentation pres = (Presentation) evt; + System.out.println(pres.getSessionId() + ": " + pres.getTitle()); + } + + } + + } + } catch (Throwable t) { + t.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new SessionsByTimeslot(), TestRunnerUtil.NATIVE_SESSION); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SessionsByTrack.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SessionsByTrack.java new file mode 100644 index 0000000..c268495 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SessionsByTrack.java @@ -0,0 +1,78 @@ +package org.openntf.conference.graph.examples; + +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.Track; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; +import org.openntf.domino.junit.TestRunnerUtil; + +import com.google.common.collect.Ordering; + +public class SessionsByTrack implements Runnable { + private long marktime; + + public SessionsByTrack() { + + } + + @Override + public void run() { + HashMap trackLkup = new HashMap(); + // trackLkup.put("Special", "Sp"); + // trackLkup.put("Strategy/Deployment", "Str"); + // trackLkup.put("Administration", "Adm"); + trackLkup.put("Development", "Dev"); + // trackLkup.put("Business", "Bus"); + // trackLkup.put("Commercial", "Comm"); + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + timelog("Beginning Sessions By Track..."); + ConferenceGraph graph = new ConferenceGraph(); + for (Entry track : trackLkup.entrySet()) { + System.out.println("Outputting sessions ordered by ID for " + track.getKey()); + + Track dev = graph.getFramedGraph().getVertex(track.getValue(), Track.class); + Iterable presentations = dev.getIncludesSessions(); + Ordering ord = Ordering.from(new DVertexFrameComparator("SessionID")); + List presOrdered = ord.sortedCopy(presentations); + for (Presentation pres : presOrdered) { + + System.out.println(pres.getSessionId() + ": " + pres.getTitle()); + } + } + + for (Entry track : trackLkup.entrySet()) { + System.out.println("Outputting sessions ordered by Title for " + track.getKey()); + + Track dev = graph.getFramedGraph().getVertex(track.getValue(), Track.class); + Iterable presentations = dev.getIncludesSessions(); + Ordering ord = Ordering.from(new DVertexFrameComparator("SessionTitle")); + List presOrdered = ord.sortedCopy(presentations); + for (Presentation pres : presOrdered) { + + System.out.println(pres.getSessionId() + ": " + pres.getTitle()); + } + } + } catch (Throwable t) { + t.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new SessionsByTrack(), TestRunnerUtil.NATIVE_SESSION); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SponsorTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SponsorTester.java new file mode 100644 index 0000000..c655c59 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/SponsorTester.java @@ -0,0 +1,55 @@ +package org.openntf.conference.graph.examples; + +import java.util.List; + +import org.openntf.conference.graph.Sponsor; +import org.openntf.conference.graph.Sponsor.Level; +import org.openntf.conferenceapp.service.SponsorFactory; +import org.openntf.domino.junit.TestRunnerUtil; + +public class SponsorTester implements Runnable { + private long marktime; + + public SponsorTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + List sponsors = SponsorFactory.getSponsorsSortedByProperty("Level"); + System.out.println("Logging sponsors....."); + for (Sponsor s : sponsors) { + System.out.println("Sponsor " + s.getLevel() + ": " + s.getName()); + System.out.println("Contact is " + SponsorFactory.getContactForSponsor(s.getName()).getEmail()); + } + System.out.println("************************"); + + System.out.println("************************"); + System.out.println("Getting Sponsors for Bronze"); + List sponsors2 = SponsorFactory.getSponsorsForLevelSortedByProperty(Level.BRONZE, null); + for (Sponsor s : sponsors2) { + System.out.println("Sponsor " + s.getName() + " - " + s.getUrl()); + } + System.out.println("************************"); + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new SponsorTester(), TestRunnerUtil.NATIVE_SESSION); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/TimeSlotTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/TimeSlotTester.java new file mode 100644 index 0000000..2f45330 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/TimeSlotTester.java @@ -0,0 +1,70 @@ +package org.openntf.conference.graph.examples; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.openntf.conference.graph.TimeSlot; +import org.openntf.conference.graph.Track; +import org.openntf.conferenceapp.service.TimeSlotFactory; +import org.openntf.conferenceapp.service.TrackFactory; +import org.openntf.domino.junit.TestRunnerUtil; + +public class TimeSlotTester implements Runnable { + private long marktime; + + public TimeSlotTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + List times = TimeSlotFactory.getTimeSlotsSortedByProperty("Starttime"); + Date dt = null; + System.out.println("Outputting all timeslots sorted on Starttime..."); + for (TimeSlot ts : times) { + if (null == dt) { + dt = ts.getStartTime().getTime(); + } + System.out.println(ts.getStartTime().getTime() + " - " + ts.getEndTime().getTime()); + } + System.out.println("***************"); + + SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd MMM"); + times = TimeSlotFactory.getOfficialTimeSlotsForDate(dt); + System.out.println("Outputting all timeslots sorted on same day as " + DATE_FORMAT.format(dt)); + for (TimeSlot ts : times) { + System.out.println(ts.getStartTime().getTime() + " - " + ts.getEndTime().getTime()); + } + System.out.println("***************"); + + System.out.println("Getting now and next for " + dt); + times = TimeSlotFactory.getSimulatedNowAndNext(dt); + for (TimeSlot ts : times) { + System.out.println(ts.getStartTime().getTime() + " - " + ts.getEndTime().getTime()); + } + System.out.println("***************"); + + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new TimeSlotTester(), TestRunnerUtil.NATIVE_SESSION); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conference/graph/examples/TrackTester.java b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/TrackTester.java new file mode 100644 index 0000000..58acf85 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conference/graph/examples/TrackTester.java @@ -0,0 +1,71 @@ +package org.openntf.conference.graph.examples; + +import java.util.List; + +import org.openntf.conference.graph.Track; +import org.openntf.conferenceapp.service.TrackFactory; +import org.openntf.domino.junit.TestRunnerUtil; + +public class TrackTester implements Runnable { + private long marktime; + + public TrackTester() { + + } + + @Override + public void run() { + long testStartTime = System.nanoTime(); + marktime = System.nanoTime(); + try { + List tracks = TrackFactory.getTracksSortedByProperty("Title"); + String trackTitle = ""; + System.out.println("Logging tracks....."); + for (Track t : tracks) { + if ("".equals(trackTitle)) { + trackTitle = t.getTitle(); + } + System.out.println("Track " + t.getTitle() + ": " + t.getDescription()); + } + System.out.println("************************"); + System.out.println("Outputting track for " + trackTitle); + Track track = TrackFactory.getTrack(trackTitle); + System.out.println("Track " + track.getTitle() + ": " + track.getDescription()); + System.out.println("************************"); + System.out.println("Getting Tracks using Gremlin"); + tracks = TrackFactory.getTracksGremlinBeforeK(); + for (Track t : tracks) { + if ("".equals(trackTitle)) { + trackTitle = t.getTitle(); + } + System.out.println("Track " + t.getTitle() + ": " + t.getDescription()); + } + System.out.println("************************"); + System.out.println("Getting Three Letter Tracks using Gremlin"); + tracks = TrackFactory.getTracksGremlinForThreeLetterTracks(); + for (Track t : tracks) { + if ("".equals(trackTitle)) { + trackTitle = t.getTitle(); + } + System.out.println("Track " + t.getTitle() + ": " + t.getDescription()); + } + System.out.println("************************"); + } catch (Exception e) { + e.printStackTrace(); + } + long testEndTime = System.nanoTime(); + System.out.println("Completed " + getClass().getSimpleName() + " run in " + ((testEndTime - testStartTime) / 1000000) + " ms"); + } + + public void timelog(final String message) { + long curtime = System.nanoTime(); + long elapsed = curtime - marktime; + marktime = curtime; + System.out.println(elapsed / 1000000 + " ms: " + message); + } + + public static void main(final String[] args) { + TestRunnerUtil.runAsDominoThread(new TrackTester(), TestRunnerUtil.NATIVE_SESSION); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/AccessControl.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/AccessControl.java new file mode 100644 index 0000000..dfb7cf2 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/AccessControl.java @@ -0,0 +1,14 @@ +package org.openntf.conferenceapp.authentication; + +public interface AccessControl { + + public boolean signIn(String username); + + public boolean isUserSignedIn(); + + public boolean isUserInRole(String role); + + public String getPrincipalName(); + + public void logout(); +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/BasicAccessControlService.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/BasicAccessControlService.java new file mode 100644 index 0000000..378f100 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/BasicAccessControlService.java @@ -0,0 +1,66 @@ +package org.openntf.conferenceapp.authentication; + +import java.util.logging.Logger; + +import javax.servlet.http.Cookie; + +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +import com.vaadin.server.VaadinService; + +public class BasicAccessControlService implements AccessControl { + + private final static Logger log = Logger.getLogger(BasicAccessControlService.class.getName()); + + @Override + public boolean signIn(String userEmail) { + + log.info("signIn " + userEmail); + + if (userEmail == null || userEmail.isEmpty()) + // TODO: @Daniele, this needs to continue as Anonymous + return false; + + // TODO: @Daniele otherwise log in as relevant user + CurrentUser.set(userEmail); + + Cookie myCookie = new Cookie("conference-uid", userEmail); + myCookie.setPath("/"); + myCookie.setMaxAge(24*60*60*31); // 1 month + + VaadinService.getCurrentResponse().addCookie(myCookie); + + log.info("clearing session identity"); + Factory.getSession(SessionType.CURRENT).clearIdentity(); + + return true; + } + + @Override + public boolean isUserSignedIn() { + return ! CurrentUser.get().isEmpty(); + } + + @Override + public boolean isUserInRole(String role) { + if ("admin".equals(role)) { + // Only the "admin" user is in the "admin" role + return getPrincipalName().equals("admin"); + } + + // All users are in all non-admin roles + return true; + } + + @Override + public String getPrincipalName() { + return CurrentUser.get(); + } + + @Override + public void logout() { + CurrentUser.set(null); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/ConferenceMembershipService.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/ConferenceMembershipService.java new file mode 100644 index 0000000..8d29889 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/ConferenceMembershipService.java @@ -0,0 +1,83 @@ +package org.openntf.conferenceapp.authentication; + +import java.util.logging.Logger; + +import org.apache.commons.mail.Email; +import org.apache.commons.mail.EmailException; +import org.apache.commons.mail.SimpleEmail; +import org.openntf.conference.graph.Attendee; +import org.openntf.conferenceapp.service.AttendeeFactory; + +import com.factor_y.util.crypto.DesEncrypter; +import com.factor_y.util.crypto.DesEncrypter.DesEncrypterException; + +public class ConferenceMembershipService { + + static DesEncrypter crypter = null; + + static { + try { + crypter = new DesEncrypter(1L, "passowrd"); + } catch (DesEncrypterException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + Logger log = Logger.getLogger(ConferenceMembershipService.class.getName()); + + public static String generateAccessToken(String email) { + + String result = null; + + try { + result = crypter.encrypt(email); + } catch (DesEncrypterException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return email; + } + + /** + * @param accessToken + * @return the Attendee Key form an access token + */ + public static String getAttendeeEmailFromAccesTokenAccessToken(String accessToken) { + String result = null; + + // try { + // result = crypter.decrypt(accessToken); + // } catch (DesEncrypterException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + + return accessToken; + } + + public static void sendInvitationEmail(String emailAddress, String token) { + + System.out.println("Sending invitation to: " + emailAddress + " url: http://engageapp.factor-y.com/ConferenceApp/app?accesstoken=" + token); + + try { + Email email = new SimpleEmail(); + email.setHostName("localhost"); + email.setSmtpPort(25); + email.setFrom("engage2015@factor-y.com", "Enage.ug 2015"); + email.setSubject("Welcome to the conference app - ACTION REQUIRED [ODA Session]"); + email.setMsg("Use this link to get access to the app and to setup your profile\n\n" + + "http://engageapp.factor-y.com/ConferenceApp/app?accesstoken=" + token); + email.addTo(emailAddress); + email.send(); + } catch (EmailException e) { + e.printStackTrace(); + } + } + + public static Attendee findUserProfileByEmail(String email) { + return AttendeeFactory.getAttendeeByEmail(email); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/CurrentUser.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/CurrentUser.java new file mode 100644 index 0000000..c14ac29 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/authentication/CurrentUser.java @@ -0,0 +1,70 @@ +package org.openntf.conferenceapp.authentication; + +import java.util.logging.Logger; + +import org.openntf.xworlds.appservers.webapp.security.SecurityManager; + +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinService; +import com.vaadin.server.VaadinServletRequest; + +public final class CurrentUser { + + private static Logger log = Logger.getLogger(CurrentUser.class.getName()); + + /** + * The attribute key used to store the username in the session. + */ + public static final String CURRENT_USER_SESSION_ATTRIBUTE_KEY = CurrentUser.class.getCanonicalName(); + + private static String getUserFullName(String userEmail) { + return "CN=" + userEmail + "/OU=ICONUK2015/O=ConferenceApp"; + } + + /** + * Returns the name of the current user stored in the current session, or an empty string if no user name is stored. + * + * @throws IllegalStateException + * if the current session cannot be accessed. + */ + public static String get() { + String currentUser = (String) getCurrentRequest().getWrappedSession().getAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY); + if (currentUser == null) { + return ""; + } else { + return currentUser; + } + } + + /** + * Sets the name of the current user and stores it in the current session. Using a {@code null} username will remove the username from the + * session. + * + * @throws IllegalStateException + * if the current session cannot be accessed. + */ + public static void set(String currentUserEmail) { + + if (currentUserEmail == null) { + getCurrentRequest().getWrappedSession().removeAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY); + // Set domino application identity + VaadinServletRequest s = (VaadinServletRequest) getCurrentRequest(); + SecurityManager.setDominoFullName(s.getHttpServletRequest(), "Anonymous"); + log.info("Identity set to anoymous"); + } else { + getCurrentRequest().getWrappedSession().setAttribute(CURRENT_USER_SESSION_ATTRIBUTE_KEY, currentUserEmail); + // Set domino application identity + VaadinServletRequest s = (VaadinServletRequest) getCurrentRequest(); + SecurityManager.setDominoFullName(s.getHttpServletRequest(), getUserFullName(currentUserEmail)); + log.info("Identity set to: " + SecurityManager.getDominoFullName(s.getHttpServletRequest())); + } + } + + private static VaadinRequest getCurrentRequest() { + VaadinRequest request = VaadinService.getCurrentRequest(); + if (request == null) { + throw new IllegalStateException("No request bound to current thread"); + } + return request; + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/components/AttendeeSummary.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/components/AttendeeSummary.java new file mode 100644 index 0000000..b326bf9 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/components/AttendeeSummary.java @@ -0,0 +1,41 @@ +package org.openntf.conferenceapp.components; + +import org.openntf.conference.graph.Attendee; + +import com.vaadin.server.ExternalResource; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Component; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Image; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +public class AttendeeSummary extends HorizontalLayout { + + public AttendeeSummary() { + + } + + public AttendeeSummary(Component... children) { + super(children); + // TODO Auto-generated constructor stub + } + + public void loadAttendeeSummary(Attendee att, int detailExpandRatio) { + setMargin(true); + Image photo = new Image("", new ExternalResource(att.getUrl())); + photo.setHeight(80, Unit.PIXELS); + VerticalLayout speakerDetails = new VerticalLayout(); + Label speakerName = new Label(att.getFirstName() + " " + att.getLastName()); + speakerName.setStyleName(ValoTheme.LABEL_H4); + Label speakerBio = new Label(att.getProfile()); + speakerDetails.addComponents(speakerName, speakerBio); + setDefaultComponentAlignment(Alignment.TOP_LEFT); + addComponents(photo, speakerDetails); + setExpandRatio(photo, 1); + setExpandRatio(speakerDetails, detailExpandRatio); + setSizeFull(); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/components/EngageHeaderComponent.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/components/EngageHeaderComponent.java new file mode 100644 index 0000000..2af1425 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/components/EngageHeaderComponent.java @@ -0,0 +1,26 @@ +package org.openntf.conferenceapp.components; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.Label; + +public class EngageHeaderComponent extends CustomComponent { + + /** + * + */ + private static final long serialVersionUID = 4465325630005163198L; + Label banner = null; + + public EngageHeaderComponent() { + setHeight("90px"); + + banner = new Label( + "
"); + banner.setCaptionAsHtml(true); + banner.setContentMode(ContentMode.HTML); + + setCompositionRoot(banner); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/components/IconHeaderComponent.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/components/IconHeaderComponent.java new file mode 100644 index 0000000..a581a35 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/components/IconHeaderComponent.java @@ -0,0 +1,26 @@ +package org.openntf.conferenceapp.components; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.Label; + +public class IconHeaderComponent extends CustomComponent { + + /** + * + */ + private static final long serialVersionUID = 4465325630005163198L; + Label banner = null; + + public IconHeaderComponent() { + setHeight("90px"); + + banner = new Label( + "
"); + banner.setCaptionAsHtml(true); + banner.setContentMode(ContentMode.HTML); + + setCompositionRoot(banner); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/ConnectedApplication.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/ConnectedApplication.java new file mode 100644 index 0000000..853d314 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/ConnectedApplication.java @@ -0,0 +1,27 @@ +package org.openntf.conferenceapp.rest; + +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +@ApplicationPath("/api") +public class ConnectedApplication extends Application { + + @Override + public Set> getClasses() { + return super.getClasses(); + } + + @Override + public Set getSingletons() { + Set sings = new HashSet(); + sings.add(new ProfilesController()); + sings.add(new EventsController()); + return super.getSingletons(); + } + + + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/EventsController.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/EventsController.java new file mode 100644 index 0000000..2cb8d9b --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/EventsController.java @@ -0,0 +1,48 @@ +package org.openntf.conferenceapp.rest; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.domino.graph2.impl.DGraph; + +import com.tinkerpop.frames.FramedElement; +import com.tinkerpop.frames.FramedTransactionalGraph; + +@Path("/graph/{graphname}") +public class EventsController { + + @GET + @Path("/meta") + public Response getGraphMetaData() { + return Response.ok().entity("Not implemented").type(MediaType.TEXT_PLAIN).build(); + } + + @GET + @Path("/v/{vertexclass}") + public Response getPresentations( + @PathParam("vertexclass") String vertexClassName) { + + // Initialize the graph + ConferenceGraph graph = new ConferenceGraph(); + Class vertexClass = null; + try { + vertexClass = (Class) Class.forName("org.openntf.conference.graph."+vertexClassName); + } catch (ClassNotFoundException e) { + return Response.serverError().entity(e.getMessage()).build(); + } + + FramedTransactionalGraph framedGraph = graph.getFramedGraph(); + Iterable pres = framedGraph.getVertices(null, null, vertexClass); + + for (FramedElement framedElement : pres) { + System.out.println(); + } + + return Response.ok().type(MediaType.APPLICATION_JSON_TYPE).entity("ok").build(); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/ProfilesController.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/ProfilesController.java new file mode 100644 index 0000000..1edbd6b --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/ProfilesController.java @@ -0,0 +1,53 @@ +package org.openntf.conferenceapp.rest; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +@Path("/profiles") +public class ProfilesController { + + /** + * @param request + * @return + */ + @POST + @Path("/person") + public Response newOrExistingProfile(@Context HttpServletRequest request) { + + return null; + } + + @PUT + @Path("/person") + public Response updateProfileInfo( + @QueryParam("fisrtname") String FirstName, + @QueryParam("lastname") String LastName) { + + return null; + } + + /** + * @param profilekey + * @return + */ + @GET + @Path("/person/{profilekey}") + public Response getProfileData(@PathParam("profilekey") String profilekey) { + + return null; + } + + @POST + @Path("/group") + public Response newOrExistingGroup() { + return null; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/RoomsController.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/RoomsController.java new file mode 100644 index 0000000..be52332 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/rest/RoomsController.java @@ -0,0 +1,25 @@ +package org.openntf.conferenceapp.rest; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import org.openntf.domino.Database; +import org.openntf.domino.Session; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +@Path("/rooms") +public class RoomsController { + + @GET + public Response getSessions() { + + Session s = Factory.getSession(SessionType.NATIVE); + + Database db = s.getDatabase("Lotussphere/sphere2015.nsf"); + + return Response.ok().entity(db.getTitle()).build(); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/AttendeeFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/AttendeeFactory.java new file mode 100644 index 0000000..ebf4ab8 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/AttendeeFactory.java @@ -0,0 +1,173 @@ +package org.openntf.conferenceapp.service; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.Track; +import org.openntf.domino.graph2.DGraph; +import org.openntf.domino.utils.Strings; + +import com.google.common.collect.Lists; +import com.tinkerpop.frames.FramedGraph; +import com.tinkerpop.frames.FramedTransactionalGraph; + +import javolution.util.FastSet; + +/** + * Factory class for access to Attendees / Speakers + * + * @author Paul Stephen Withers + * + */ +public class AttendeeFactory { + + /** + * Retrieves a specific Attendee based on email address + * + * @param email + * String primary email of the user + * @return Attendee corresponding to the email + */ + @SuppressWarnings("unchecked") + public static Attendee getAttendeeByEmail(String email) { + + FramedTransactionalGraph framedGraph = (FramedTransactionalGraph) ConferenceGraphFactory.getGraph("engage"); + + Iterable vs = framedGraph.getVertices("Email", email, Attendee.class); + if (vs.iterator().hasNext()) { + return vs.iterator().next(); + } else { + return null; + } + } + + /** + * Adds an attendee using a Map of properties, validating before attempting + * an insertion + * + * @param props + * Map of properties + * @return Attendee successfully entered or String of errors + */ + @SuppressWarnings("unchecked") + public static Attendee addAttendee(Map props) { + Attendee retVal_ = null; + try { + ArrayList missingProps = new ArrayList(); + validateProperties(props, missingProps, "Firstname"); + validateProperties(props, missingProps, "Lastname"); + if (!props.containsKey("Email") && !props.containsKey("Twitter")) { + missingProps.add("Email or Twitter Username"); + } + if (!missingProps.isEmpty()) { + String missing = Strings.join(missingProps, ","); + throw new IllegalStateException(missing); + } + + FramedTransactionalGraph framedGraph = (FramedTransactionalGraph) ConferenceGraphFactory.getGraph("engage"); + String key = ""; + if (props.containsKey("Email")) { + key = (String) props.get("Email"); + } else { + key = (String) props.get("Twitter"); + } + Attendee att = framedGraph.addVertex(key, Attendee.class); + att.setFirstName((String) props.get("Firstname")); + att.setLastName((String) props.get("Lastname")); + updateAttendeeProps(props, att); + + framedGraph.commit(); + + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + /** + * Updates properties for the relevant Attendee + * + * @param props + * Map of properties and values to update + * @param att + * Attendee to update + */ + private static void updateAttendeeProps(Map props, Attendee att) { + if (props.containsKey("Email")) { + att.setEmail((String) props.get("Email")); + } + if (props.containsKey("Email")) { + att.setTwitterId((String) props.get("Twitter")); + } + if (props.containsKey("Country")) { + att.setCountry((String) props.get("Country")); + } + if (props.containsKey("Facebook")) { + att.setFacebookId((String) props.get("Facebook")); + } + if (props.containsKey("Url")) { + att.setUrl((String) props.get("Url")); + } + if (props.containsKey("Phone")) { + att.setPhone((String) props.get("Phone")); + } + if (props.containsKey("Profile")) { + att.setProfile((String) props.get("Profile")); + } + if (props.containsKey("Role")) { + att.setRole((String) props.get("Role")); + } + } + + /** + * Validates a given property have been supplied + * + * @param props + * Map of properties to validate against + * @param missingProps + * ArrayList of properties not supplied + * @param check + * String property to check for + */ + private static void validateProperties(Map props, ArrayList missingProps, String check) { + if (!props.containsKey(check)) { + missingProps.add(check); + } + } + + /** + * Gets a FastSet of Speaker Attendee objects for the relevant Track + * + * @param trackKey + * String key for the Trackk to check + * @return FastSet Speakers for the given track + */ + @SuppressWarnings("unchecked") + public static FastSet getSpeakers(String trackKey) { + FastSet retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + List presentations = new ArrayList(); + FastSet speakers = new FastSet(); + if (Strings.isBlankString(trackKey)) { + presentations = Lists.newArrayList(graph.getVertices(null, null, Presentation.class)); + } else { + Track track = TrackFactory.getTrack(trackKey); + presentations = Lists.newArrayList(track.getIncludesSessions()); + } + for (Presentation pres : presentations) { + List presSpeakers = Lists.newArrayList(pres.getPresentingAttendees()); + speakers.addAll(presSpeakers); + } + return speakers; + + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/ConferenceGraphFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/ConferenceGraphFactory.java new file mode 100644 index 0000000..799577d --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/ConferenceGraphFactory.java @@ -0,0 +1,71 @@ +package org.openntf.conferenceapp.service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openntf.conference.graph.ConferenceGraph; + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.tinkerpop.frames.FramedGraph; + +public class ConferenceGraphFactory { + + private static Map registeredGraphs = new HashMap(); + public static String ENGAGE_KEY = "engage"; + + static void registerConference(String conferenceKey, ConferenceGraph graph) { + Preconditions.checkNotNull(conferenceKey, "The conference name/key cannot be null"); + Preconditions.checkNotNull(graph, "The conference graph cannot be null"); + + registeredGraphs.put(conferenceKey, graph); + } + + /** + * @return a list of available Conference graphs + */ + static List getAvailableConferences() { + return Lists.newArrayList(registeredGraphs.keySet()); + } + + static ConferenceManager getConferenceManager(String conferenceName) { + return null; + } + + public static ConferenceGraph getConference(final String key) { + ConferenceGraph retVal_ = null; + try { + if (!registeredGraphs.containsKey(key)) { + retVal_ = new ConferenceGraph(); + registerConference(key, retVal_); + } else { + retVal_ = registeredGraphs.get(key); + } + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + public static FramedGraph getGraph(final String confName) { + return getConference(confName).getFramedGraph(); + } + + /** + * Gets FramedGraph for graph with key "engage", else creates new + * ConferenceGraph + * + * @return FramedGraph for Engage + */ + static FramedGraph getEngageGraph() { + ConferenceGraph graph = null; + if (!registeredGraphs.containsKey(ENGAGE_KEY)) { + graph = new ConferenceGraph(); + registerConference(ENGAGE_KEY, graph); + } else { + graph = registeredGraphs.get(ENGAGE_KEY); + } + return getConference(ENGAGE_KEY).getFramedGraph(); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/ConferenceManager.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/ConferenceManager.java new file mode 100644 index 0000000..bc56d3d --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/ConferenceManager.java @@ -0,0 +1,5 @@ +package org.openntf.conferenceapp.service; + +public class ConferenceManager { + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/EventFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/EventFactory.java new file mode 100644 index 0000000..c72758e --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/EventFactory.java @@ -0,0 +1,114 @@ +package org.openntf.conferenceapp.service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javolution.util.FastSet; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Event; +import org.openntf.conference.graph.Location; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; + +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; +import com.ibm.commons.util.StringUtil; +import com.tinkerpop.frames.FramedGraph; +import com.tinkerpop.gremlin.java.GremlinPipeline; + +public class EventFactory { + + static boolean debug = false; + + public static List getPresentationsSortedByProperty(String property) { + List retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + Iterable presentations = graph.getVertices(null, null, Presentation.class); + if (StringUtil.isEmpty(property)) { + property = "SessionID"; + } + Ordering ord = Ordering.from(new DVertexFrameComparator(property)); + retVal_ = ord.sortedCopy(presentations); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + public static FastSet getPresentationsByTimeSlot(Object ts) { + FastSet retVal_ = new FastSet(); + List times = new ArrayList(); + if (null == ts) { + times = TimeSlotFactory.getTimeSlotsSorted(); + } else if (ts instanceof TimeSlot) { + times.add((TimeSlot) ts); + } else if (ts instanceof List) { + times = (List) ts; + } else if (ts instanceof Date) { + times = TimeSlotFactory.getOfficialTimeSlotsForDate((Date) ts); + } + for (TimeSlot time : times) { + Iterable presentations = time.getEvents(); + for (Event evt : presentations) { + if (evt instanceof Presentation) { + retVal_.add((Presentation) evt); + } + + } + + } + return retVal_; + } + + public static FastSet getPresentationsByLocation(Object loc) { + FastSet retVal_ = new FastSet(); + List locations = new ArrayList(); + if (null == loc) { + locations = LocationFactory.getLocationsSortedByProperty(""); + } else if (loc instanceof Location) { + locations.add((Location) loc); + } else if (loc instanceof List) { + locations = (List) loc; + } + for (Location location : locations) { + Iterable presentations = location.getEvents(); + for (Event evt : presentations) { + if (evt instanceof Presentation) { + retVal_.add((Presentation) evt); + } + + } + + } + return retVal_; + } + + // This throws a ClassCastException currently + // java.lang.ClassCastException: com.sun.proxy.$Proxy11 incompatible with + // com.tinkerpop.blueprints.Vertex + // Because outV returns a FramedVertex and needs to return .asVertex() + public static List getSpeakers(String trackKey) { + List retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + List presentations = Lists.newArrayList(graph.getVertices(null, null, Presentation.class)); + + // GremlinPipeline pipe = new + // GremlinPipeline(presentations).outE("PresentedBy").outV().dedup(); + GremlinPipeline pipe = new GremlinPipeline(presentations).outE("PresentedBy").outV(); + // List edges = pipe.toList(); + // for (DEdge edge : edges) { + // System.out.println(edge.getVertex(Direction.OUT).getId()); + // } + retVal_ = pipe.toList(); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/LocationFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/LocationFactory.java new file mode 100644 index 0000000..ed3c110 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/LocationFactory.java @@ -0,0 +1,58 @@ +package org.openntf.conferenceapp.service; + +import java.util.ArrayList; +import java.util.List; + +import org.openntf.conference.graph.Location; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; + +import com.google.common.collect.Ordering; +import com.ibm.commons.util.StringUtil; +import com.tinkerpop.frames.FramedGraph; + +public class LocationFactory { + + /** + * Gets all Location in the graph, sorted on the property passed, or "Name" + * if an empty String is passed + * + * @param property + * String property to sort on. If empty String passed, default of + * "Name" is used. + * @return ArrayList sorted on property, or empty ArrayList if + * nothing found or error encountered + */ + public static List getLocationsSortedByProperty(String property) { + List retVal_ = new ArrayList(); + try { + FramedGraph graph = ConferenceGraphFactory.getEngageGraph(); + Iterable locations = graph.getVertices(null, null, Location.class); + if (StringUtil.isEmpty(property)) { + property = "Name"; + } + Ordering ord = Ordering.from(new DVertexFrameComparator(property)); + retVal_ = ord.sortedCopy(locations); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + /** + * Gets a Location for the relevant key + * + * @param key + * String for Location name + * @return Location or null if no location found or error encountered + */ + public static Location getLocation(String key) { + Location retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getEngageGraph(); + retVal_ = (Location) graph.getVertex(key, Location.class); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/SponsorFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/SponsorFactory.java new file mode 100644 index 0000000..1c7b72c --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/SponsorFactory.java @@ -0,0 +1,73 @@ +package org.openntf.conferenceapp.service; + +import java.util.Iterator; +import java.util.List; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Sponsor; +import org.openntf.conference.graph.Sponsor.Level; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; + +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; +import com.ibm.commons.util.StringUtil; +import com.tinkerpop.frames.FramedGraph; + +public class SponsorFactory { + + static boolean debug = false; + + public static List getSponsorsSortedByProperty(String property) { + List retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + Iterable sponsors = graph.getVertices(null, null, Sponsor.class); + if (StringUtil.isEmpty(property)) { + property = "Name"; + } + Ordering ord = Ordering.from(new DVertexFrameComparator(property)); + retVal_ = ord.sortedCopy(sponsors); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + public static List getSponsorsForLevelSortedByProperty(Level level, String property) { + List retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + List sponsors = Lists.newArrayList(graph.getVertices(null, null, Sponsor.class)); + Iterator it = sponsors.iterator(); + while (it.hasNext()) { + if (!level.equals(((Sponsor) it.next()).getLevel())) { + it.remove(); + } + } + + if (StringUtil.isEmpty(property)) { + property = "Name"; + } + Ordering ord = Ordering.from(new DVertexFrameComparator(property)); + retVal_ = ord.sortedCopy(sponsors); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + public static Attendee getContactForSponsor(String sponsorName) { + Attendee retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + Sponsor sponsor = (Sponsor) graph.getVertex(sponsorName, Sponsor.class); + if (null != sponsor) { + retVal_ = sponsor.getContactAttendees().iterator().next(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/TimeSlotFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/TimeSlotFactory.java new file mode 100644 index 0000000..1cdd4b1 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/TimeSlotFactory.java @@ -0,0 +1,128 @@ +package org.openntf.conferenceapp.service; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +import org.openntf.conference.graph.ConferenceGraph; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; + +import com.google.common.collect.Ordering; +import com.ibm.commons.util.StringUtil; +import com.ibm.icu.util.Calendar; + +public class TimeSlotFactory { + + public static List getOfficialTimeSlotsForDate(Date dt) { + List retVal_ = new ArrayList(); + // Get date as dd MMM + if (null == dt) { + dt = new Date(); + } + SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd MMM"); + Calendar cal = Calendar.getInstance(); + cal.setTime(dt); + String day = DATE_FORMAT.format(cal.getTime()); + + // Now get all TimeSlots + ConferenceGraph graph = ConferenceGraphFactory.getConference(ConferenceGraphFactory.ENGAGE_KEY); + Iterable times = graph.getTimeSlots(); + Iterator it = times.iterator(); + while (it.hasNext()) { + TimeSlot ts = (TimeSlot) it.next(); + if (day.equals(ts.getDay()) && ts.getOfficial() == 1) { + retVal_.add(ts); + } + } + + // Now sort on time + Ordering ord = Ordering.from(new DVertexFrameComparator("Starttime")); + retVal_ = ord.sortedCopy(retVal_); + + return retVal_; + } + + public static List getTimeSlotsSortedByProperty(String property) { + List retVal_ = new ArrayList(); + + ConferenceGraph graph = ConferenceGraphFactory.getConference(ConferenceGraphFactory.ENGAGE_KEY); + Iterable times = graph.getTimeSlots(); + + // Now sort on time + if (StringUtil.isEmpty(property)) { + property = "Starttime"; + } + Ordering ord = Ordering.from(new DVertexFrameComparator(property)); + retVal_ = ord.sortedCopy(times); + + return retVal_; + } + + public static List getTimeSlotsSorted() { + List retVal_ = new ArrayList(); + Ordering byStart = new Ordering() { + + @Override + public int compare(final TimeSlot t1, final TimeSlot t2) { + return t1.getStartTime().compareTo(t2.getStartTime()); + } + }; + + ConferenceGraph graph = ConferenceGraphFactory.getConference(ConferenceGraphFactory.ENGAGE_KEY); + Iterable times = graph.getTimeSlots(); + retVal_ = byStart.sortedCopy(times); + return retVal_; + } + + public static List getNowAndNext() { + List retVal_ = new ArrayList(); + + // TODO: UK TIME + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + cal.add(Calendar.HOUR, 1); + retVal_ = getSimulatedNowAndNext(cal.getTime()); + + return retVal_; + } + + public static List getSimulatedNowAndNext(Date dt) { + List retVal_ = new ArrayList(); + + ConferenceGraph graph = ConferenceGraphFactory.getConference(ConferenceGraphFactory.ENGAGE_KEY); + Iterable times = graph.getTimeSlots(); + List nextTimes = new ArrayList(); + Iterator it = times.iterator(); + while (it.hasNext()) { + TimeSlot ts = (TimeSlot) it.next(); + // Ignore, TimeSlot already ended + // Ignore if StartTime more than one hour after now, remove + if (ts.getOfficial() == 1) { + if (dt.before(ts.getEndTime().getTime())) { + Calendar check = Calendar.getInstance(); + check.setTime(ts.getStartTime().getTime()); + check.add(Calendar.MINUTE, -1); + if (dt.after(check.getTime())) { + // Currently running + retVal_.add(ts); + } else { + nextTimes.add(ts); + } + } + } + } + + // Now sort on time + if (!nextTimes.isEmpty()) { + Ordering ord = Ordering.from(new DVertexFrameComparator("Starttime")); + nextTimes = ord.sortedCopy(nextTimes); + retVal_.add(nextTimes.get(0)); + } + + return retVal_; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/TrackFactory.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/TrackFactory.java new file mode 100644 index 0000000..01f8519 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/TrackFactory.java @@ -0,0 +1,149 @@ +package org.openntf.conferenceapp.service; + +import java.util.ArrayList; +import java.util.List; + +import org.openntf.conference.graph.Track; +import org.openntf.domino.graph2.builtin.DVertexFrameComparator; + +import com.google.common.collect.Lists; +import com.google.common.collect.Ordering; +import com.ibm.commons.util.StringUtil; +import com.tinkerpop.frames.FramedGraph; +import com.tinkerpop.gremlin.java.GremlinPipeline; +import com.tinkerpop.pipes.PipeFunction; +import com.tinkerpop.pipes.util.structures.Pair; + +public class TrackFactory { + + /** + * Gets all Tracks in the graph, sorted on the property passed, or "Title" + * if an empty String is passed + * + * @param property + * String property to sort on. If empty String passed, default of + * "Title" is used. Other property for a Track is "Description" + * @return ArrayList sorted on property, or empty ArrayList if + * nothing found or error encountered + */ + public static List getTracksSortedByProperty(String property) { + List retVal_ = new ArrayList(); + try { + FramedGraph graph = ConferenceGraphFactory.getEngageGraph(); + Iterable tracks = graph.getVertices(null, null, Track.class); + if (StringUtil.isEmpty(property)) { + property = "Title"; + } + Ordering ord = Ordering.from(new DVertexFrameComparator(property)); + retVal_ = ord.sortedCopy(tracks); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + @SuppressWarnings("unchecked") + public static List getTracksGremlinBeforeK() { + List retVal_ = new ArrayList(); + try { + FramedGraph graph = ConferenceGraphFactory.getEngageGraph(); + List tracks = Lists.newArrayList(graph.getVertices(null, null, Track.class)); + // Can't seem to get the compare to work, but here it is + PipeFunction, Integer> strCompare = new PipeFunction, Integer>() { + + @Override + public Integer compute(Pair arg0) { + System.out.println("Comparing..."); + System.out.println("**Comparing " + arg0.getA().getTitle() + " with " + arg0.getB().getTitle()); + String elem1 = arg0.getA().getTitle(); + String elem2 = arg0.getB().getTitle(); + Integer ord = elem1.compareToIgnoreCase(elem2); + System.out.println(ord); + return ord; + } + + }; + PipeFunction strFilter = new PipeFunction() { + + @Override + public Boolean compute(Track t) { + Integer beforeK = t.getTitle().compareToIgnoreCase("K"); + if (beforeK < 0) { + return true; + } else { + return false; + } + } + + }; + // GremlinPipeline pipe = new GremlinPipeline(tracks).add(new + // OrderPipe(strCompare)).back(1); + GremlinPipeline pipe = new GremlinPipeline(tracks).filter(strFilter).back(1); + retVal_ = pipe.toList(); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + @SuppressWarnings("unchecked") + public static List getTracksGremlinForThreeLetterTracks() { + List retVal_ = new ArrayList(); + try { + FramedGraph graph = ConferenceGraphFactory.getEngageGraph(); + List tracks = Lists.newArrayList(graph.getVertices(null, null, Track.class)); + // Can't seem to get the compare to work, but here it is + PipeFunction, Integer> strCompare = new PipeFunction, Integer>() { + + @Override + public Integer compute(Pair arg0) { + System.out.println("Comparing..."); + System.out.println("**Comparing " + arg0.getA().getTitle() + " with " + arg0.getB().getTitle()); + String elem1 = arg0.getA().getTitle(); + String elem2 = arg0.getB().getTitle(); + Integer ord = elem1.compareToIgnoreCase(elem2); + System.out.println(ord); + return ord; + } + + }; + PipeFunction strFilter = new PipeFunction() { + + @Override + public Boolean compute(String t) { + if (t.length() == 3) { + return true; + } else { + return false; + } + } + + }; + // GremlinPipeline pipe = new GremlinPipeline(tracks).add(new + // OrderPipe(strCompare)).back(1); + GremlinPipeline pipe = new GremlinPipeline(tracks).property("Title").filter(strFilter).back(2); + retVal_ = pipe.toList(); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } + + /** + * Gets a track for the relevant key + * + * @param key + * String for Track, e.g. "Dev" + * @return Track or null if no track found or error encountered + */ + public static Track getTrack(String key) { + Track retVal_ = null; + try { + FramedGraph graph = ConferenceGraphFactory.getEngageGraph(); + retVal_ = (Track) graph.getVertex(key, Track.class); + } catch (Exception e) { + e.printStackTrace(); + } + return retVal_; + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/service/package-info.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/package-info.java new file mode 100644 index 0000000..17e6ec6 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/service/package-info.java @@ -0,0 +1,11 @@ +/** + * The service package includes the business logic (controller) that manages and controls the behaviour of the + * conference graph. + * + * A factory object allows the instantiation of the graph controller. + * + * Every conference interaction is then exposed as a method in the controller + * + */ + +package org.openntf.conferenceapp.service; \ No newline at end of file diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/ConferenceUI.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/ConferenceUI.java new file mode 100644 index 0000000..5f45405 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/ConferenceUI.java @@ -0,0 +1,128 @@ +package org.openntf.conferenceapp.ui; + +import java.text.SimpleDateFormat; +import java.util.logging.Logger; + +import javax.servlet.http.Cookie; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conferenceapp.authentication.AccessControl; +import org.openntf.conferenceapp.authentication.BasicAccessControlService; +import org.openntf.conferenceapp.authentication.ConferenceMembershipService; +import org.openntf.conferenceapp.ui.pages.MainScreen; +import org.openntf.conferenceapp.ui.pages.SessionsFilter; +import org.openntf.conferenceapp.ui.pages.login.LoginScreen; +import org.openntf.conferenceapp.ui.pages.login.LoginScreen.LoginListener; +import org.openntf.conferenceapp.ui.pages.profile.ProfileCreationScreen; +import org.openntf.conferenceapp.ui.pages.profile.ProfileView; + +import com.vaadin.annotations.Theme; +import com.vaadin.annotations.Viewport; +import com.vaadin.server.Responsive; +import com.vaadin.server.VaadinRequest; +import com.vaadin.ui.UI; +import com.vaadin.ui.themes.ValoTheme; + +@Viewport("user-scalable=no,initial-scale=1.0") +@SuppressWarnings("serial") +@Theme("conferenceApp") +public class ConferenceUI extends UI { + + private static Logger log = Logger.getLogger(ConferenceUI.class.getName()); + + public static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("hh:mm"); + private AccessControl accessControlService = new BasicAccessControlService(); + + private ProfileView profileView; + + @Override + protected void init(VaadinRequest request) { + Responsive.makeResponsive(this); + + getPage().setTitle("[OpenNTF] ICON UK 2015"); + + if (request.getParameter("logout") != null) { + accessControlService.logout(); + } + + /* + * When I get an access token I try to validate it, if valid I extract the user identity and lookup the attendee profile. + * + * If the profile exists I move to the common navigation otherwhise I open the profile management view to create the Attendee profile + * + */ + + if (!accessControlService.isUserSignedIn()) { + // User not logged in + // check if has access token + + String accessToken = null; + String attendeeEmail = null; + + // Check for an access token in the URL + if ((accessToken = request.getParameter("accesstoken")) != null) { + + log.info("Access token is available on URL: " + accessToken); + attendeeEmail = ConferenceMembershipService.getAttendeeEmailFromAccesTokenAccessToken(accessToken); + + Attendee attendee = ConferenceMembershipService.findUserProfileByEmail(attendeeEmail); + + if (attendee == null) { + setContent(new ProfileCreationScreen(this, attendeeEmail)); + } else { + accessControlService.signIn(attendeeEmail); + showMainView(); + } + + } else { + + // otherwise check if has cookie, in case setup login + for (Cookie cookie : request.getCookies()) { + if (cookie.getName().equals("conference-uid")) { + attendeeEmail = ConferenceMembershipService.getAttendeeEmailFromAccesTokenAccessToken(cookie.getValue()); + log.info("Performing login based on cookie identity " + attendeeEmail); + accessControlService.signIn(attendeeEmail); + showMainView(); + } + } + + if (attendeeEmail == null) { + // otherwise goto loginscreen + setContent(new LoginScreen(accessControlService, new LoginListener() { + @Override + public void loginSuccessful() { + showMainView(); + } + })); + } + } + } else { + // if loggedin goto mainview + showMainView(); + } + + } + + public void showMainView() { + + addStyleName(ValoTheme.UI_WITH_MENU); + + // Load mainScreen and restore state + setContent(new MainScreen(this)); + + if ("".equals(getNavigator().getState())) { + getNavigator().navigateTo(SessionsFilter.VIEW_NAME); + } else { + getNavigator().navigateTo(getNavigator().getState()); + } + } + + public static ConferenceUI get() { + return (ConferenceUI) UI.getCurrent(); + } + + public AccessControl getAccessControl() { + return accessControlService; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/ConferenceUIServlet.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/ConferenceUIServlet.java new file mode 100644 index 0000000..6aac51f --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/ConferenceUIServlet.java @@ -0,0 +1,73 @@ +package org.openntf.conferenceapp.ui; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; + +import com.vaadin.annotations.VaadinServletConfiguration; +import com.vaadin.server.BootstrapFragmentResponse; +import com.vaadin.server.BootstrapListener; +import com.vaadin.server.BootstrapPageResponse; +import com.vaadin.server.ServiceException; +import com.vaadin.server.SessionInitEvent; +import com.vaadin.server.SessionInitListener; +import com.vaadin.server.VaadinServlet; + +@WebServlet(value = { "/app/*" , "/VAADIN/*" }, asyncSupported = true) +@VaadinServletConfiguration(productionMode = false, ui = ConferenceUI.class) +public class ConferenceUIServlet extends VaadinServlet { + + @Override + protected void servletInitialized() throws ServletException { + super.servletInitialized(); + + getService().addSessionInitListener(new SessionInitListener() { + + @Override + public void sessionInit(SessionInitEvent event) throws ServiceException { + + event.getSession().addBootstrapListener(new BootstrapListener() { + + @Override + public void modifyBootstrapPage(final BootstrapPageResponse response) { + +// String contextPath = response.getRequest().getContextPath(); + + response.getDocument().head().append( + "" + + "" + + "" + ); + + response.getDocument().head().append( + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + + "" + ); + + } + + @Override + public void modifyBootstrapFragment(BootstrapFragmentResponse response) { + // TODO Auto-generated method stub + + } + }); + + } + }); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/CalendarView.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/CalendarView.java new file mode 100644 index 0000000..140a036 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/CalendarView.java @@ -0,0 +1,94 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.util.Date; +import java.util.List; + +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.conferenceapp.service.EventFactory; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.ui.Calendar; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.components.calendar.event.CalendarEvent; + +public class CalendarView extends VerticalLayout implements View { + + public static final String VIEW_NAME = "CalendarView"; + public static final String VIEW_DESC = "On calendar"; + + @Override + public void enter(ViewChangeEvent event) { + // TODO Auto-generated method stub + + } + + public CalendarView() { + + Calendar cal = new Calendar(); + + cal.setStartDate(new Date(115, 8, 21)); + cal.setEndDate(new Date(115, 8, 22)); + + cal.setFirstVisibleHourOfDay(7); + cal.setLastVisibleHourOfDay(23); + cal.setReadOnly(true); + + List presentationsList = EventFactory.getPresentationsSortedByProperty(""); + + for (Presentation presentation : presentationsList) { + + final Presentation presF = presentation; + Iterable slots = presentation.getTimes(); + + for (TimeSlot timeSlot : slots) { + + final TimeSlot slotF = timeSlot; + cal.addEvent(new CalendarEvent() { + + @Override + public Date getStart() { + return slotF.getStartTime().getTime(); + } + + @Override + public Date getEnd() { + return slotF.getEndTime().getTime(); + } + + @Override + public String getCaption() { + // TODO Auto-generated method stub + return presF.getTitle(); + } + + @Override + public String getDescription() { + // TODO Auto-generated method stub + return presF.getDescription(); + } + + @Override + public String getStyleName() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean isAllDay() { + // TODO Auto-generated method stub + return false; + } + + }); + } + } + + cal.setSizeFull(); + + addComponent(cal); + setWidth(100, Unit.PERCENTAGE); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/ErrorView.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/ErrorView.java new file mode 100644 index 0000000..c508a95 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/ErrorView.java @@ -0,0 +1,35 @@ +package org.openntf.conferenceapp.ui.pages; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.Reindeer; + +/** + * View shown when trying to navigate to a view that does not exist using + * {@link com.vaadin.navigator.Navigator}. + * + * + */ +public class ErrorView extends VerticalLayout implements View { + + private Label explanation; + + public ErrorView() { + setMargin(true); + setSpacing(true); + + Label header = new Label("The view could not be found"); + header.addStyleName(Reindeer.LABEL_H1); + addComponent(header); + addComponent(explanation = new Label()); + } + + @Override + public void enter(ViewChangeListener.ViewChangeEvent event) { + explanation.setValue(String.format( + "You tried to navigate to a view ('%s') that does not exist.", + event.getViewName())); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/MainScreen.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/MainScreen.java new file mode 100644 index 0000000..e0aeea7 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/MainScreen.java @@ -0,0 +1,132 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.util.HashMap; + +import org.openntf.conferenceapp.components.IconHeaderComponent; +import org.openntf.conferenceapp.ui.ConferenceUI; +import org.openntf.conferenceapp.ui.pages.profile.ProfileView; + +import com.vaadin.navigator.Navigator; +import com.vaadin.navigator.ViewChangeListener; +import com.vaadin.server.Resource; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.VerticalLayout; + +/** + * Content of the UI when the user is logged in. + * + * + */ +public class MainScreen extends VerticalLayout { + private NavigableMenuBar menu; + + public MainScreen(ConferenceUI ui) { + + setStyleName("main-screen"); + + addComponent(new IconHeaderComponent()); + + CssLayout viewContainer = new CssLayout(); + viewContainer.addStyleName("valo-content"); + viewContainer.setSizeFull(); + + final Navigator navigator = new Navigator(ui, viewContainer); + navigator.setErrorView(ErrorView.class); + menu = new NavigableMenuBar(navigator); + menu.setStyleName("menuArea"); + addComponent(menu); + + navigator.addViewChangeListener(menu); + + // Only used for demos, not a "modern" user experience! + // navigator.addView(TraditionalView.VIEW_NAME, new TraditionalView()); + // menu.addView(TraditionalView.VIEW_NAME, TraditionalView.VIEW_DESC, null); + + navigator.addView(SessionsFilter.VIEW_NAME, new SessionsFilter()); + menu.addView(SessionsFilter.VIEW_NAME, SessionsFilter.VIEW_DESC, null); + + navigator.addView(NowAndNext.VIEW_NAME, new NowAndNext()); + menu.addView(NowAndNext.VIEW_NAME, NowAndNext.VIEW_DESC, null); + + navigator.addView(Sponsors.VIEW_NAME, new Sponsors()); + menu.addView(Sponsors.VIEW_NAME, Sponsors.VIEW_DESC, null); + + navigator.addView(CalendarView.VIEW_NAME, new CalendarView()); + menu.addView(CalendarView.VIEW_NAME, CalendarView.VIEW_DESC, null); + + navigator.addView(Speakers.VIEW_NAME, new Speakers()); + menu.addView(Speakers.VIEW_NAME, Speakers.VIEW_DESC, null); + + navigator.addView(ProfileView.VIEW_NAME, new ProfileView()); + menu.addView(ProfileView.VIEW_NAME, ProfileView.VIEW_DESC, null); + + addComponent(viewContainer); + setExpandRatio(viewContainer, 1); + setSizeFull(); + } + + /** A menu bar that both controls and observes navigation */ + protected class NavigableMenuBar extends MenuBar implements ViewChangeListener { + private MenuItem previous = null; // Previously selected item + private MenuItem current = null; // Currently selected item + + // Map view IDs to corresponding menu items + HashMap menuItems = new HashMap(); + + private Navigator navigator = null; + + public NavigableMenuBar(Navigator navigator) { + this.navigator = navigator; + } + + /** Navigate to a view by menu selection */ + MenuBar.Command mycommand = new MenuBar.Command() { + public void menuSelected(MenuItem selectedItem) { + String viewName = selectItem(selectedItem); + navigator.navigateTo(viewName); + } + }; + + public void addView(String viewName, String caption, Resource icon) { + menuItems.put(viewName, addItem(caption, icon, mycommand)); + } + + /** Select a menu item by its view ID **/ + protected boolean selectView(String viewName) { + // Check that the menu item exists + if (!menuItems.containsKey(viewName)) + return false; + + if (previous != null) + previous.setStyleName(null); + if (current == null) + current = menuItems.get(viewName); + current.setStyleName("highlight"); + previous = current; + + return true; + } + + /** Selects a new menu item */ + public String selectItem(MenuItem selectedItem) { + current = selectedItem; + + // Do reverse lookup for the view ID + for (String key : menuItems.keySet()) + if (menuItems.get(key) == selectedItem) + return key; + + return null; + } + + @Override + public boolean beforeViewChange(ViewChangeEvent event) { + return selectView(event.getViewName()); + } + + @Override + public void afterViewChange(ViewChangeEvent event) { + } + }; +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/NowAndNext.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/NowAndNext.java new file mode 100644 index 0000000..fab430c --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/NowAndNext.java @@ -0,0 +1,236 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.text.DateFormatSymbols; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Location; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.conference.graph.Track; +import org.openntf.conferenceapp.service.EventFactory; +import org.openntf.conferenceapp.service.TimeSlotFactory; +import org.openntf.conferenceapp.ui.ConferenceUI; + +import com.google.gwt.thirdparty.guava.common.collect.Lists; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.server.FontAwesome; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +public class NowAndNext extends CssLayout implements View { + + private static final long serialVersionUID = 1L; + private boolean RUN_SIMULATED = true; + public static final String VIEW_NAME = "NowAndNext"; + public static final String VIEW_DESC = "Now and Next"; + List times; + public boolean isLoaded = false; + + public NowAndNext() { + + } + + @Override + public void enter(ViewChangeEvent event) { + if (!isLoaded) { + if (RUN_SIMULATED) { + loadSimulatedNowAndNext(); + } else { + loadNowAndNext(); + } + loadContent(); + isLoaded = true; + } + } + + public List getTimes() { + return times; + } + + public void setTimes(List times) { + this.times = times; + } + + public void loadNowAndNext() { + setTimes(TimeSlotFactory.getNowAndNext()); + } + + public void loadSimulatedNowAndNext() { + List times = TimeSlotFactory.getTimeSlotsSortedByProperty("Starttime"); + TimeSlot ts = times.get(0); + Date dt = ts.getStartTime().getTime(); + setTimes(TimeSlotFactory.getSimulatedNowAndNext(dt)); + } + + public void loadContent() { + try { + + setSizeFull(); + + // We're always having a header, even if it's to say + // "This isn't active yet" + if (getTimes().isEmpty()) { + // Not yet active, log and quit + final HorizontalLayout top = new HorizontalLayout(); + top.setDefaultComponentAlignment(Alignment.TOP_LEFT); + top.addStyleName(ValoTheme.MENU_TITLE); + top.setSpacing(true); + Label title = new Label("Now and next is only active during the conference"); + title.setSizeUndefined(); + top.addComponent(title); + addComponent(top); + return; + } + + // Get time and number of sessions occurring then + TimeSlot ts1 = getTimes().get(0); + Date currDate = new Date(); + if (RUN_SIMULATED) { + Calendar tmpCal = ts1.getStartTime(); + tmpCal.add(Calendar.MINUTE, 10); + currDate = tmpCal.getTime(); + } + loadSessionsForTime(ts1, "Now", currDate); + if (getTimes().size() > 1) { + TimeSlot ts2 = getTimes().get(1); + loadSessionsForTime(ts2, "Next", currDate); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void loadSessionsForTime(TimeSlot ts, String label, Date passedDate) { + final HorizontalLayout top = new HorizontalLayout(); + top.setDefaultComponentAlignment(Alignment.TOP_LEFT); + top.addStyleName(ValoTheme.MENU_TITLE); + top.setSpacing(true); + Iterable presentations = EventFactory.getPresentationsByTimeSlot(ts); + String minutes; + if ("Now".equals(label)) { + minutes = Integer.toString(minutesDiff(passedDate, ts.getEndTime().getTime())) + " minutes remaining)"; + } else { + minutes = Integer.toString(minutesDiff(passedDate, ts.getStartTime().getTime())) + " minutes to start)"; + } + Label title = new Label(label + getCountMsg(presentations) + minutes); + title.setSizeUndefined(); + top.addComponent(title); + addComponent(top); + + for (final Presentation pres : presentations) { + // Load speaker details + final Iterable speakers = pres.getPresentingAttendees(); + String speakerNames = ""; + for (Attendee att : speakers) { + if ("".equals(speakerNames)) { + speakerNames = att.getFirstName() + " " + att.getLastName(); + } else { + speakerNames += ", " + att.getFirstName() + " " + att.getLastName(); + } + } + final String passedSpeakers = speakerNames; + + HorizontalLayout sessionRow = new HorizontalLayout(); + sessionRow.setWidth(100, Unit.PERCENTAGE); + Track track = pres.getIncludedInTracks().iterator().next(); + Label trackLabel = new Label(); + trackLabel.setDescription(track.getDescription()); + trackLabel.setValue(getTrackHtml(track.getTitle())); + trackLabel.setWidth(25, Unit.PIXELS); + trackLabel.setContentMode(ContentMode.HTML); + sessionRow.addComponent(trackLabel); + sessionRow.setComponentAlignment(trackLabel, Alignment.MIDDLE_CENTER); + VerticalLayout sessionDetails = new VerticalLayout(); + sessionDetails.setWidth(100, Unit.PERCENTAGE); + Button presTitle = new Button(pres.getSessionId() + " - " + pres.getTitle()); + presTitle.setStyleName(ValoTheme.BUTTON_LINK); + presTitle.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + SessionDetailsDialog sub = new SessionDetailsDialog(); + sub.setSessionTitle(pres.getTitle()); + sub.setSessionDesc(pres.getDescription()); + sub.setSpeakers(speakers); + sub.loadContent(); + + // Add it to the root component + UI.getCurrent().addWindow(sub); + } + }); + sessionDetails.addComponent(presTitle); + DateFormatSymbols s = new DateFormatSymbols(UI.getCurrent().getLocale()); + String[] days = s.getShortWeekdays(); + String dayTime = days[ts.getStartTime().get(Calendar.DAY_OF_WEEK)] + " " + ConferenceUI.TIME_FORMAT.format(ts.getStartTime().getTime()) + + "-" + ConferenceUI.TIME_FORMAT.format(ts.getEndTime().getTime()); + Location loc = pres.getLocations().iterator().next(); + sessionDetails.addComponent(new Label(dayTime + "|" + loc.getName())); + sessionRow.addComponent(sessionDetails); + sessionRow.setExpandRatio(trackLabel, 1); + sessionRow.setExpandRatio(sessionDetails, 19); + addComponent(sessionRow); + } + + Label gap = new Label(); + gap.setHeight("1em"); + addComponent(gap); + } + + public String getTrackHtml(String trackCode) { + String iconCode; + if ("Sp".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.STAR.getCodepoint()) + ";"; + } else if ("Str".equals(trackCode)) { + iconCode = "&#x" + Integer.toHexString(FontAwesome.QUESTION_CIRCLE.getCodepoint()) + ";"; + } else if ("Bus".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.BRIEFCASE.getCodepoint()) + ";"; + } else if ("Adm".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.TERMINAL.getCodepoint()) + ";"; + } else if ("Dev".equals(trackCode)) { + iconCode = "&#x" + Integer.toHexString(FontAwesome.STACK_OVERFLOW.getCodepoint()) + ";"; + } else if ("Comm".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.EURO.getCodepoint()) + ";"; + } else { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.CIRCLE.getCodepoint()) + ";"; + } + return iconCode; + } + + public int minutesDiff(Date earlierDate, Date laterDate) { + if (earlierDate == null || laterDate == null) + return 0; + + return (int) ((laterDate.getTime() / 60000) - (earlierDate.getTime() / 60000)); + } + + public String getCountMsg(Iterable pres) { + List presentations = Lists.newArrayList(pres); + if (presentations.size() < 2) { + return " (" + presentations.size() + " session "; + } else { + return " (" + presentations.size() + " sessions "; + } + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/PresentationsContainer.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/PresentationsContainer.java new file mode 100644 index 0000000..0b079c0 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/PresentationsContainer.java @@ -0,0 +1,112 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Location; +import org.openntf.conference.graph.Presentation; +import org.openntf.conference.graph.TimeSlot; +import org.openntf.conference.graph.Track; +import org.openntf.conferenceapp.service.ConferenceGraphFactory; + +import com.tinkerpop.frames.FramedGraph; +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; + +public class PresentationsContainer { + + // Create the container + public IndexedContainer container; + public Boolean removeDesc = true; + + public PresentationsContainer() { + + loadData(); + } + + public PresentationsContainer(boolean removeDesc) { + + setRemoveDesc(false); + loadData(); + } + + private Boolean getRemoveDesc() { + return removeDesc; + } + + private void setRemoveDesc(Boolean removeDesc) { + this.removeDesc = removeDesc; + } + + private void loadData() { + // Define the properties (columns) + container = new IndexedContainer(); + container.addContainerProperty("SessionID", String.class, ""); + container.addContainerProperty("Title", String.class, ""); + container.addContainerProperty("Track", String.class, ""); + container.addContainerProperty("Speakers", String.class, ""); + container.addContainerProperty("Speaker1", Attendee.class, null); + container.addContainerProperty("Speaker2", Attendee.class, null); + container.addContainerProperty("Speaker3", Attendee.class, null); + container.addContainerProperty("Speaker4", Attendee.class, null); + container.addContainerProperty("Day", String.class, ""); + container.addContainerProperty("StartTime", Date.class, ""); + container.addContainerProperty("EndTime", Date.class, ""); + container.addContainerProperty("Location", String.class, ""); + container.addContainerProperty("Description", String.class, ""); + + FramedGraph graph = ConferenceGraphFactory.getGraph("engage"); + SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd MMM"); + Iterable presentations = graph.getVertices(null, null, Presentation.class); + for (Presentation pres : presentations) { + Item newItem = container.getItem(container.addItem()); + newItem.getItemProperty("SessionID").setValue(pres.getSessionId()); + newItem.getItemProperty("Title").setValue(pres.getTitle()); + Track track = pres.getIncludedInTracks().iterator().next(); + newItem.getItemProperty("Track").setValue(track.getTitle()); + Iterable speakers = pres.getPresentingAttendees(); + Integer x = 1; + String speakerNames = ""; + for (Attendee att : speakers) { + if ("".equals(speakerNames)) { + speakerNames = att.getFirstName() + " " + att.getLastName(); + } else { + speakerNames += ", " + att.getFirstName() + " " + att.getLastName(); + } + newItem.getItemProperty("Speaker" + x.toString()).setValue(att); + x++; + } + newItem.getItemProperty("Speakers").setValue(speakerNames); + TimeSlot ts = pres.getTimes().iterator().next(); + newItem.getItemProperty("Day").setValue(DATE_FORMAT.format(ts.getStartTime().getTime())); + newItem.getItemProperty("StartTime").setValue(ts.getStartTime().getTime()); + newItem.getItemProperty("EndTime").setValue(ts.getEndTime().getTime()); + Location loc = pres.getLocations().iterator().next(); + newItem.getItemProperty("Location").setValue(loc.getName()); + newItem.getItemProperty("Description").setValue(pres.getDescription()); + } + + if (getRemoveDesc()) { + container.removeContainerProperty("Description"); + } + } + + public void filterGrid(String type, String value) { + if ("All".equals(value)) { + container.removeContainerFilters(type); + } else { + container.removeContainerFilters(type); + container.addContainerFilter(type, value, false, false); + } + } + + public IndexedContainer getContainer() { + return container; + } + + public void setContainer(IndexedContainer container) { + this.container = container; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/SessionDetailsDialog.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/SessionDetailsDialog.java new file mode 100644 index 0000000..4998c0b --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/SessionDetailsDialog.java @@ -0,0 +1,65 @@ +package org.openntf.conferenceapp.ui.pages; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conferenceapp.components.AttendeeSummary; + +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Label; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.Window; +import com.vaadin.ui.themes.ValoTheme; + +public class SessionDetailsDialog extends Window { + private static final long serialVersionUID = 1L; + private String sessionTitle; + private String sessionDesc; + private Iterable speakers; + + public SessionDetailsDialog() { + super("Session Details"); // Set window caption + center(); + } + + public void loadContent() { + // Some basic content for the window + VerticalLayout content = new VerticalLayout(); + Label title = new Label(getSessionTitle()); + title.setStyleName(ValoTheme.LABEL_H3); + content.addComponent(title); + Label desc = new Label(getSessionDesc()); + desc.setContentMode(ContentMode.HTML); + content.addComponent(desc); + for (Attendee att : getSpeakers()) { + AttendeeSummary speakerArea = new AttendeeSummary(); + speakerArea.loadAttendeeSummary(att, 9); + content.addComponent(speakerArea); + } + + content.setMargin(true); + setContent(content); + } + + public String getSessionTitle() { + return sessionTitle; + } + + public void setSessionTitle(String sessionTitle) { + this.sessionTitle = sessionTitle; + } + + public String getSessionDesc() { + return sessionDesc; + } + + public void setSessionDesc(String sessionDesc) { + this.sessionDesc = sessionDesc; + } + + public Iterable getSpeakers() { + return speakers; + } + + public void setSpeakers(Iterable speakers) { + this.speakers = speakers; + } +} \ No newline at end of file diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/SessionsFilter.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/SessionsFilter.java new file mode 100644 index 0000000..fd83894 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/SessionsFilter.java @@ -0,0 +1,335 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.text.DateFormatSymbols; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Location; +import org.openntf.conference.graph.Track; +import org.openntf.conferenceapp.service.LocationFactory; +import org.openntf.conferenceapp.service.TrackFactory; +import org.openntf.conferenceapp.ui.ConferenceUI; + +import com.vaadin.data.Item; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.server.FontAwesome; +import com.vaadin.server.Resource; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Notification.Type; +import com.vaadin.ui.UI; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +public class SessionsFilter extends VerticalLayout implements View { + + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String VIEW_NAME = "SessionsFilter"; + public static final String VIEW_DESC = "Sessions By..."; + private PresentationsContainer presentations; + private VerticalLayout details = new VerticalLayout(); + private VerticalLayout main = new VerticalLayout(); + MenuBar menubar = new MenuBar(); + MenuItem tracks; + MenuItem locations; + MenuItem days; + + public SessionsFilter() { + main.setSpacing(true); + + menubar.setStyleName(ValoTheme.MENU_SUBTITLE); + menubar.setWidth(100, Unit.PERCENTAGE); + menubar.addItem("Sessions By...", null); + tracks = menubar.addItem("Filter by Track", null, null); + MenuItem allTracks = tracks.addItem("All", trackFilterCommand); + allTracks.setStyleName("highlight"); + for (Track track : TrackFactory.getTracksSortedByProperty("")) { + MenuItem t = tracks.addItem(track.getDescription(), getIcon(track.getTitle()), trackFilterCommand); + } + locations = menubar.addItem("Filter by Location", null, null); + MenuItem allLocs = locations.addItem("All", locationFilterCommand); + allLocs.setStyleName("highlight"); + for (Location loc : LocationFactory.getLocationsSortedByProperty("")) { + MenuItem l = locations.addItem(loc.getName(), locationFilterCommand); + } + days = menubar.addItem("Filter by Date", null); + MenuItem allDays = days.addItem("All", dayFilterCommand); + allDays.setStyleName("highlight"); + // days.addItem("30 Mar", dayFilterCommand); + // days.addItem("31 Mar", dayFilterCommand); + days.addItem("21 Sep", dayFilterCommand); + days.addItem("22 Sep", dayFilterCommand); + + addComponent(menubar); + + } + + public void loadContent() { + try { + + presentations = new PresentationsContainer(false); + + loadData(); + + main.addComponent(details); + main.setComponentAlignment(details, Alignment.TOP_CENTER); + addComponent(main); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void loadData() { + String catLabel = ""; + DateFormatSymbols s = new DateFormatSymbols(UI.getCurrent().getLocale()); + String[] days = s.getShortWeekdays(); + + details.removeAllComponents(); + + details.setWidth(95, Unit.PERCENTAGE); + IndexedContainer table = presentations.getContainer(); + table.sort(new Object[] { "StartTime" }, new boolean[] { true }); + + // Iterate over the item identifiers of the table. + for (Iterator i = table.getItemIds().iterator(); i.hasNext();) { + // Get the current item identifier, which is an integer. + int iid = (Integer) i.next(); + + // Now get the actual item from the + final Item item = table.getItem(iid); + + Date sTime = (Date) item.getItemProperty("StartTime").getValue(); + Date eTime = (Date) item.getItemProperty("EndTime").getValue(); + String tmpCatLabel = days[sTime.getDay() + 1] + " " + ConferenceUI.TIME_FORMAT.format(sTime) + "-" + + ConferenceUI.TIME_FORMAT.format(eTime); + if (!tmpCatLabel.equals(catLabel)) { + Label cat = new Label(tmpCatLabel); + cat.setStyleName(ValoTheme.LABEL_H3); + details.addComponent(cat); + catLabel = tmpCatLabel; + } + + HorizontalLayout sessionDetails = new HorizontalLayout(); + sessionDetails.setWidth(100, Unit.PERCENTAGE); + + // Add track + Label trackLabel = new Label(); + trackLabel.setDescription((String) item.getItemProperty("Track").getValue()); + trackLabel.setValue(getTrackHtml((String) item.getItemProperty("Track").getValue())); + trackLabel.setWidth(25, Unit.PIXELS); + trackLabel.setContentMode(ContentMode.HTML); + sessionDetails.addComponent(trackLabel); + + VerticalLayout sessionSummary = new VerticalLayout(); + sessionSummary.setWidth(100, Unit.PERCENTAGE); + Button title = new Button(item.getItemProperty("SessionID").getValue() + " - " + item.getItemProperty("Title").getValue()); + title.setStyleName(ValoTheme.BUTTON_LINK); + title.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + SessionDetailsDialog sub = new SessionDetailsDialog(); + sub.setSessionTitle((String) item.getItemProperty("Title").getValue()); + sub.setSessionDesc((String) item.getItemProperty("Description").getValue()); + ArrayList speakers = new ArrayList(); + for (Integer j = 1; j < 4; j++) { + if (null != item.getItemProperty("Speaker" + j.toString()).getValue()) { + speakers.add((Attendee) item.getItemProperty("Speaker" + j.toString()).getValue()); + } + } + sub.setSpeakers(speakers); + sub.loadContent(); + + // Add it to the root component + UI.getCurrent().addWindow(sub); + } + }); + sessionSummary.addComponent(title); + sessionSummary + .addComponent(new Label(item.getItemProperty("Speakers").getValue() + " (" + item.getItemProperty("Location").getValue() + ")")); + sessionDetails.addComponent(sessionSummary); + + sessionDetails.setExpandRatio(sessionSummary, 1); + details.addComponent(sessionDetails); + } + + } + + public String getTrackHtml(String trackCode) { + String iconCode; + if ("Sp".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.STAR.getCodepoint()) + ";"; + } else if ("Str".equals(trackCode)) { + iconCode = "&#x" + Integer.toHexString(FontAwesome.QUESTION_CIRCLE.getCodepoint()) + ";"; + } else if ("Bus".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.BRIEFCASE.getCodepoint()) + ";"; + } else if ("Adm".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.TERMINAL.getCodepoint()) + ";"; + } else if ("Dev".equals(trackCode)) { + iconCode = "&#x" + Integer.toHexString(FontAwesome.STACK_OVERFLOW.getCodepoint()) + ";"; + } else if ("Comm".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.EURO.getCodepoint()) + ";"; + } else if ("1".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.TERMINAL.getCodepoint()) + ";"; + } else if ("3".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.BOLT.getCodepoint()) + ";"; + } else if ("4".equals(trackCode)) { + iconCode = "&#x" + Integer.toHexString(FontAwesome.STACK_OVERFLOW.getCodepoint()) + ";"; + } else if ("5".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.STAR.getCodepoint()) + ";"; + } else if ("6".equals(trackCode)) { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.BRIEFCASE.getCodepoint()) + ";"; + } else { + iconCode = "&#x" + + Integer.toHexString(FontAwesome.CIRCLE.getCodepoint()) + ";"; + } + return iconCode; + } + + public Resource getIcon(String trackCode) { + Resource iconCode; + if ("Sp".equals(trackCode)) { + iconCode = FontAwesome.STAR; + } else if ("Str".equals(trackCode)) { + iconCode = FontAwesome.QUESTION_CIRCLE; + } else if ("Bus".equals(trackCode)) { + iconCode = FontAwesome.BRIEFCASE; + } else if ("Adm".equals(trackCode)) { + iconCode = FontAwesome.TERMINAL; + } else if ("Dev".equals(trackCode)) { + iconCode = FontAwesome.STACK_OVERFLOW; + } else if ("Comm".equals(trackCode)) { + iconCode = FontAwesome.EURO; + } else if ("1".equals(trackCode)) { + iconCode = FontAwesome.TERMINAL; + } else if ("3".equals(trackCode)) { + iconCode = FontAwesome.BOLT; + } else if ("4".equals(trackCode)) { + iconCode = FontAwesome.STACK_OVERFLOW; + } else if ("5".equals(trackCode)) { + iconCode = FontAwesome.STAR; + } else if ("6".equals(trackCode)) { + iconCode = FontAwesome.BRIEFCASE; + } else { + iconCode = FontAwesome.CIRCLE; + } + return iconCode; + } + + MenuBar.Command trackFilterCommand = new MenuBar.Command() { + MenuItem previous = null; + + public void menuSelected(MenuItem selectedItem) { + String trackCode = "All"; + for (Track t : TrackFactory.getTracksSortedByProperty("")) { + if (selectedItem.getText().equals(t.getDescription())) { + trackCode = t.getTitle(); + } + } + + main.removeComponent(details); + presentations.filterGrid("Track", trackCode); + loadData(); + main.addComponent(details); + main.setComponentAlignment(details, Alignment.TOP_CENTER); + + if (previous == null) { + previous = tracks.getChildren().get(0); + } + + previous.setStyleName(null); + selectedItem.setStyleName("highlight"); + previous = selectedItem; + if ("All".equals(selectedItem.getText())) { + menubar.getItems().get(1).setStyleName(null); + } else { + menubar.getItems().get(1).setStyleName("highlight"); + } + } + }; + + MenuBar.Command locationFilterCommand = new MenuBar.Command() { + MenuItem previous = null; + + public void menuSelected(MenuItem selectedItem) { + presentations.filterGrid("Location", selectedItem.getText()); + main.removeComponent(details); + loadData(); + main.addComponent(details); + main.setComponentAlignment(details, Alignment.TOP_CENTER); + + if (previous == null) { + previous = locations.getChildren().get(0); + } + + previous.setStyleName(null); + selectedItem.setStyleName("highlight"); + previous = selectedItem; + if ("All".equals(selectedItem.getText())) { + menubar.getItems().get(2).setStyleName(null); + } else { + menubar.getItems().get(2).setStyleName("highlight"); + } + } + }; + + MenuBar.Command dayFilterCommand = new MenuBar.Command() { + MenuItem previous = null; + + public void menuSelected(MenuItem selectedItem) { + main.removeComponent(details); + presentations.filterGrid("Day", selectedItem.getText()); + loadData(); + main.addComponent(details); + main.setComponentAlignment(details, Alignment.TOP_CENTER); + + if (previous == null) { + previous = days.getChildren().get(0); + } + + previous.setStyleName(null); + selectedItem.setStyleName("highlight"); + previous = selectedItem; + if ("All".equals(selectedItem.getText())) { + menubar.getItems().get(3).setStyleName(null); + } else { + menubar.getItems().get(3).setStyleName("highlight"); + } + } + }; + + public void showError(String msg) { + Notification.show(msg, Type.ERROR_MESSAGE); + } + + @Override + public void enter(ViewChangeEvent event) { + loadContent(); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/Speakers.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/Speakers.java new file mode 100644 index 0000000..57c04ea --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/Speakers.java @@ -0,0 +1,148 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.TreeMap; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conference.graph.Track; +import org.openntf.conferenceapp.components.AttendeeSummary; +import org.openntf.conferenceapp.service.AttendeeFactory; +import org.openntf.conferenceapp.service.TrackFactory; + +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.OptionGroup; +import com.vaadin.ui.VerticalLayout; + +public class Speakers extends CssLayout implements View { + private static final long serialVersionUID = 1L; + public static final String VIEW_NAME = "Speakers"; + public static final String VIEW_DESC = "Speakers"; + private VerticalLayout content = new VerticalLayout(); + private List panels = new ArrayList(); + private HashMap> trackSpeakers = new HashMap>(); + private OptionGroup trackSelector = new OptionGroup(); + boolean contentLoaded = false; + + public Speakers() { + + } + + @Override + public void enter(ViewChangeEvent event) { + if (!contentLoaded) { + loadContent(); + } + contentLoaded = true; + } + + public void loadContent() { + try { + getContent().setWidth(100, Unit.PERCENTAGE); + getContent().setDefaultComponentAlignment(Alignment.TOP_CENTER); + + // Load speakers + HashMap> tmpTrackSpeakers = new HashMap>(); + TreeMap allSpeakers = new TreeMap(); + for (Track track : TrackFactory.getTracksSortedByProperty("")) { + TreeMap currTrackSpeakers = new TreeMap(); + for (Attendee att : AttendeeFactory.getSpeakers(track.getTitle())) { + currTrackSpeakers.put(att.getFirstName() + " " + att.getLastName(), att); + allSpeakers.put(att.getFirstName() + " " + att.getLastName(), att); + } + tmpTrackSpeakers.put(track.getTitle(), currTrackSpeakers); + trackSelector.addItem(track.getTitle()); + trackSelector.setItemCaption(track.getTitle(), track.getDescription()); + } + tmpTrackSpeakers.put("All", allSpeakers); + setTrackSpeakers(tmpTrackSpeakers); + + getTrackSelector().addItem("All"); + getTrackSelector().setItemCaption("All", "All"); + getTrackSelector().setImmediate(true); + getTrackSelector().addValueChangeListener(new ValueChangeListener() { + private static final long serialVersionUID = 1L; + + @Override + public void valueChange(ValueChangeEvent event) { + redrawSpeakers((String) event.getProperty().getValue()); + } + }); + getTrackSelector().setValue("All"); + getTrackSelector().addStyleName("horizontal"); + getTrackSelector().setSizeUndefined(); + + redrawSpeakers("All"); + addComponent(getContent()); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void redrawSpeakers(String trackKey) { + try { + getContent().removeAllComponents(); + getContent().addComponent(getTrackSelector()); + TreeMap currTrackSpeakers = getTrackSpeakers().get(trackKey); + HorizontalLayout attendeePanel = new HorizontalLayout(); + attendeePanel.setWidth(100, Unit.PERCENTAGE); + int x = 1; + for (Attendee att : currTrackSpeakers.values()) { + AttendeeSummary panel = new AttendeeSummary(); + panel.loadAttendeeSummary(att, 2); + attendeePanel.addComponent(panel); + if (x == 3) { + getContent().addComponent(attendeePanel); + attendeePanel = new HorizontalLayout(); + attendeePanel.setWidth(100, Unit.PERCENTAGE); + x = 1; + } else { + x++; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public List getPanels() { + return panels; + } + + public void setPanels(List panels) { + this.panels = panels; + } + + public HashMap> getTrackSpeakers() { + return trackSpeakers; + } + + public void setTrackSpeakers(HashMap> trackSpeakers) { + this.trackSpeakers = trackSpeakers; + } + + public VerticalLayout getContent() { + return content; + } + + public void setContent(VerticalLayout content) { + this.content = content; + } + + public OptionGroup getTrackSelector() { + return trackSelector; + } + + public void setTrackSelector(OptionGroup trackSelector) { + this.trackSelector = trackSelector; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/Sponsors.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/Sponsors.java new file mode 100644 index 0000000..d8e7439 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/Sponsors.java @@ -0,0 +1,168 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.util.ArrayList; +import java.util.List; + +import org.openntf.conference.graph.Sponsor; +import org.openntf.conference.graph.Sponsor.Level; +import org.openntf.conferenceapp.service.SponsorFactory; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.server.FontAwesome; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar; +import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +public class Sponsors extends CssLayout implements View { + + private static final long serialVersionUID = 1L; + public static final String VIEW_NAME = "Sponsors"; + public static final String VIEW_DESC = "Sponsors"; + private List panels = new ArrayList(); + boolean contentLoaded = false; + MenuBar menubar = new MenuBar(); + + public Sponsors() { + + } + + @Override + public void enter(ViewChangeEvent event) { + if (!contentLoaded) { + loadContent(); + } + contentLoaded = true; + } + + public void loadContent() { + try { + VerticalLayout main = new VerticalLayout(); + main.setSpacing(true); + + menubar.addStyleName(ValoTheme.MENU_SUBTITLE); + menubar.setWidth(100, Unit.PERCENTAGE); + MenuItem item = menubar.addItem(Level.PLATINUM.name(), filterSponsorsCommand); + item.setStyleName("highlight"); + // menubar.addItem(Level.PLATINUM.name(), filterSponsorsCommand); + menubar.addItem(Level.GOLD.name(), filterSponsorsCommand); + menubar.addItem(Level.SILVER.name(), filterSponsorsCommand); + menubar.addItem(Level.BRONZE.name(), filterSponsorsCommand); + addComponent(menubar); + + // Get time and number of sessions occurring then + // VerticalLayout stratDetails = + // loadSponsorsForLevel(Level.STRATEGIC, main); + // stratDetails.setDescription(Level.STRATEGIC.name()); + // main.addComponent(stratDetails); + // panels.add(stratDetails); + VerticalLayout platDetails = loadSponsorsForLevel(Level.PLATINUM, main); + platDetails.setDescription(Level.PLATINUM.name()); + main.addComponent(platDetails); + panels.add(platDetails); + VerticalLayout goldDetails = loadSponsorsForLevel(Level.GOLD, main); + goldDetails.setVisible(false); + goldDetails.setDescription(Level.GOLD.name()); + main.addComponent(goldDetails); + panels.add(goldDetails); + VerticalLayout silverDetails = loadSponsorsForLevel(Level.SILVER, main); + silverDetails.setVisible(false); + silverDetails.setDescription(Level.SILVER.name()); + main.addComponent(silverDetails); + panels.add(silverDetails); + VerticalLayout bronzeDetails = loadSponsorsForLevel(Level.BRONZE, main); + bronzeDetails.setVisible(false); + bronzeDetails.setDescription(Level.BRONZE.name()); + main.addComponent(bronzeDetails); + panels.add(bronzeDetails); + addComponent(main); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + MenuBar.Command filterSponsorsCommand = new MenuBar.Command() { + MenuItem previous = null; + + public void menuSelected(MenuItem selectedItem) { + if (previous == null) { + previous = menubar.getItems().get(0); + } + + previous.setStyleName(null); + selectedItem.setStyleName("highlight"); + previous = selectedItem; + + for (VerticalLayout l : panels) { + if (l.getDescription().equals(selectedItem.getText())) { + l.setVisible(true); + } else { + l.setVisible(false); + } + } + } + }; + + private VerticalLayout loadSponsorsForLevel(Level level, VerticalLayout container) { + VerticalLayout retVal_ = new VerticalLayout(); + final HorizontalLayout top = new HorizontalLayout(); + top.setDefaultComponentAlignment(Alignment.TOP_LEFT); + top.addStyleName(ValoTheme.MENU_TITLE); + top.setSpacing(true); + List sponsors = SponsorFactory.getSponsorsForLevelSortedByProperty(level, null); + Label title = new Label(level.name() + " " + getLevelHtml(level)); + title.setContentMode(ContentMode.HTML); + title.setSizeUndefined(); + top.addComponent(title); + retVal_.addComponent(top); + + for (final Sponsor s : sponsors) { + HorizontalLayout sessionRow = new HorizontalLayout(); + sessionRow.setWidth(95, Unit.PERCENTAGE); + Label label1 = new Label(""); + label1.setContentMode(ContentMode.HTML); + sessionRow.setDefaultComponentAlignment(Alignment.MIDDLE_CENTER); + sessionRow.addComponent(label1); + VerticalLayout sponsorDetails = new VerticalLayout(); + sponsorDetails.setWidth(100, Unit.PERCENTAGE); + Label sponsorName = new Label(s.getName()); + sponsorName.setStyleName(ValoTheme.LABEL_H2); + sponsorDetails.addComponent(sponsorName); + sponsorDetails.addComponent(new Label(s.getProfile())); + sessionRow.addComponent(sponsorDetails); + sessionRow.setExpandRatio(label1, 1); + sessionRow.setExpandRatio(sponsorDetails, 4); + retVal_.addComponent(sessionRow); + retVal_.setComponentAlignment(sessionRow, Alignment.TOP_CENTER); + } + return retVal_; + } + + public String getLevelHtml(Level level) { + String iconCode; + String starCode = "&#x" + + Integer.toHexString(FontAwesome.STAR.getCodepoint()) + ";"; + if (level.equals(Level.STRATEGIC)) { + iconCode = starCode + starCode + starCode + starCode + starCode; + } else if (level.equals(Level.PLATINUM)) { + iconCode = starCode + starCode + starCode + starCode; + } else if (level.equals(Level.GOLD)) { + iconCode = starCode + starCode + starCode; + } else if (level.equals(Level.SILVER)) { + iconCode = starCode + starCode; + } else if (level.equals(Level.BRONZE)) { + iconCode = starCode; + } else { + iconCode = ""; + } + return iconCode; + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/TraditionalView.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/TraditionalView.java new file mode 100644 index 0000000..ed835ff --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/TraditionalView.java @@ -0,0 +1,98 @@ +package org.openntf.conferenceapp.ui.pages; + +import java.text.SimpleDateFormat; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.Grid; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Notification.Type; +import com.vaadin.ui.renderers.DateRenderer; +import com.vaadin.ui.themes.ValoTheme; + +/** + * Sample for a Grid layout. Only used in demos for sessions, not recommended + * for actual applications. NOTE: Attendee column doesn't work correctly. + * + * @author Paul Stephen Withers + * + */ +public class TraditionalView extends CssLayout implements View { + + /** + * + */ + private static final long serialVersionUID = 1L; + public static final String VIEW_NAME = "TraditionalView"; + public static final String VIEW_DESC = "Traditional View"; + + public TraditionalView() { + + } + + public void showError(String msg) { + Notification.show(msg, Type.ERROR_MESSAGE); + } + + @Override + public void enter(ViewChangeEvent event) { + setSizeFull(); + final HorizontalLayout top = new HorizontalLayout(); + top.setDefaultComponentAlignment(Alignment.TOP_LEFT); + top.addStyleName(ValoTheme.MENU_TITLE); + top.setSpacing(true); + Label title = new Label("Traditonal 'View-style' Navigation"); + title.setSizeUndefined(); + top.addComponent(title); + addComponent(top); + Label info = new Label("Click on Session ID, Title, Start Time or Location columns to re-sort on those columns"); + addComponent(info); + Label gap = new Label(); + gap.setHeight("1em"); + addComponent(gap); + + Grid tradGrid = new Grid(); + tradGrid.setSizeFull(); + + PresentationsContainer presentations = new PresentationsContainer(); + tradGrid.setContainerDataSource(presentations.getContainer()); + Grid.Column col = tradGrid.getColumn("SessionID"); + col.setHeaderCaption("Session ID"); + col.setSortable(true); + col = tradGrid.getColumn("Title"); + col.setSortable(true); + col.setWidth(400); + col = tradGrid.getColumn("Track"); + col.setSortable(true); + // col = grid.getColumn("Description"); + // col.setSortable(true); + // col.setWidth(300); + col = tradGrid.getColumn("Speakers"); + col.setWidth(200); + col = tradGrid.getColumn("Day"); + col.setSortable(true); + col.setWidth(80); + col = tradGrid.getColumn("StartTime"); + col.setHeaderCaption("Start Time"); + col.setSortable(true); + col.setRenderer(new DateRenderer(new SimpleDateFormat("hh:mm"))); + col = tradGrid.getColumn("EndTime"); + col.setHeaderCaption("End Time"); + col.setSortable(true); + col.setRenderer(new DateRenderer(new SimpleDateFormat("hh:mm"))); + col = tradGrid.getColumn("Location"); + col.setWidth(80); + col.setSortable(true); + tradGrid.setFrozenColumnCount(2); + tradGrid.setColumnOrder("SessionID", "Title", "Track", "Speakers", "Day", "StartTime", "EndTime", "Location"); + setWidth(100, Unit.PERCENTAGE); + setSizeFull(); + + addComponent(tradGrid); + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/login/LoginScreen.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/login/LoginScreen.java new file mode 100644 index 0000000..881102c --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/login/LoginScreen.java @@ -0,0 +1,182 @@ +package org.openntf.conferenceapp.ui.pages.login; + +import java.io.Serializable; +import java.util.logging.Logger; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conferenceapp.authentication.AccessControl; +import org.openntf.conferenceapp.authentication.ConferenceMembershipService; +import org.openntf.conferenceapp.service.AttendeeFactory; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +import com.vaadin.data.validator.EmailValidator; +import com.vaadin.event.ShortcutAction; +import com.vaadin.server.Page; +import com.vaadin.server.VaadinService; +import com.vaadin.server.VaadinServletRequest; +import com.vaadin.shared.ui.label.ContentMode; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.Button; +import com.vaadin.ui.Component; +import com.vaadin.ui.CssLayout; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.Notification; +import com.vaadin.ui.TextField; +import com.vaadin.ui.VerticalLayout; +import com.vaadin.ui.themes.ValoTheme; + +public class LoginScreen extends CssLayout { + + private static Logger log = Logger.getLogger(LoginScreen.class.getName()); + /** + * + */ + private static final long serialVersionUID = -1486180911093854206L; + private TextField userEmailField; + private Button login; + private LoginListener loginListener; + private AccessControl accessControl; + private ConferenceMembershipService membershipService; + + public LoginScreen(AccessControl accessControl, LoginListener loginListener) { + this.loginListener = loginListener; + this.accessControl = accessControl; + this.membershipService = new ConferenceMembershipService(); + + buildUI(); + } + + private void buildUI() { + addStyleName("login-screen"); + + // login form, centered in the available part of the screen + Component loginForm = buildLoginForm(); + + // layout to center login form when there is sufficient screen space + // - see the theme for how this is made responsive for various screen + // sizes + VerticalLayout centeringLayout = new VerticalLayout(); + centeringLayout.setStyleName("centering-layout"); + centeringLayout.addComponent(loginForm); + centeringLayout.setComponentAlignment(loginForm, Alignment.MIDDLE_CENTER); + + // information text about logging in + CssLayout loginInformation = buildLoginInformation(); + + addComponent(centeringLayout); + addComponent(loginInformation); + } + + private Component buildLoginForm() { + FormLayout loginForm = new FormLayout(); + + loginForm.addStyleName("login-form"); + loginForm.setSizeUndefined(); + loginForm.setMargin(false); + loginForm.setHeight("160px"); + + userEmailField = new TextField("Email address"); +// username.addFocusListener(new FocusListener() { +// +// @Override +// public void focus(FocusEvent event) { +// TextField parent = (TextField) event.getComponent(); +// parent.setValue(""); +// } +// }); + loginForm.addComponent(userEmailField); + userEmailField.setWidth(15, Unit.EM); + userEmailField.setInputPrompt("Your email here"); + userEmailField.setDescription("Use your email address to get a personal profile."); + userEmailField.setRequired(true); + userEmailField.setRequiredError("Email must be provided to get a profile"); + userEmailField.addValidator(new EmailValidator("The user id can only be email")); + userEmailField.setId("username"); + + CssLayout buttons = new CssLayout(); + buttons.setStyleName("buttons"); + loginForm.addComponent(buttons); + + buttons.addComponent(login = new Button("Enter the conference")); + login.setDisableOnClick(true); + login.addClickListener(new Button.ClickListener() { + @Override + public void buttonClick(Button.ClickEvent event) { + try { + performAccessWithEmail(); + } finally { + login.setEnabled(true); + } + } + }); + login.setClickShortcut(ShortcutAction.KeyCode.ENTER); + login.addStyleName(ValoTheme.BUTTON_FRIENDLY); + + return loginForm; + } + + private CssLayout buildLoginInformation() { + CssLayout loginInformation = new CssLayout(); + loginInformation.setStyleName("login-information"); + Label loginInfoText = new Label("

Engage.UG 2015

" + + "You can access conference information as anonymous or get a personal profile.
" + "
" + + "Visit the app as anonymous or provide your email to get an access link.
" + "
" + + "The access link will set a cookie for you to easily (no password needed) access the app", ContentMode.HTML); + loginInformation.addComponent(loginInfoText); + return loginInformation; + } + + private void performAccessWithEmail() { + + if (! userEmailField.isValid()) { + return; + } + + String userEmail = userEmailField.getValue().toLowerCase(); + + Attendee attendee = null; + + VaadinServletRequest req = (VaadinServletRequest) VaadinService.getCurrentRequest(); + + log.warning(Factory.getSession(SessionType.CURRENT).getEffectiveUserName()); + Factory.getSession(SessionType.CURRENT).clearIdentity(); + + attendee = AttendeeFactory.getAttendeeByEmail(userEmail); + + if (attendee != null) { + showNotification(new Notification("Great, you have a profile", "Check your email for the link to access the app", + Notification.Type.HUMANIZED_MESSAGE)); + + log.info("User profile exists for: " + userEmailField.getValue() + ", sending reminder invitation"); + + String userIdentityToken = membershipService.generateAccessToken(userEmailField.getValue()); + membershipService.sendInvitationEmail(userEmail, userIdentityToken); + } else { + // Send email for creating the user profile + + log.info("User profile not found for: " + userEmailField.getValue() + ", sending invitation"); + + showNotification(new Notification("Almost there", "Great !!!

Check your email, a message is on it's way to help you setup a profile", + Notification.Type.HUMANIZED_MESSAGE)); + userEmailField.focus(); + + String userIdentityToken = membershipService.generateAccessToken(userEmailField.getValue()); + membershipService.sendInvitationEmail(userEmail, userIdentityToken); + } + + } + + private void showNotification(Notification notification) { + // keep the notification visible a little while after moving the + // mouse, or until clicked + notification.setDelayMsec(2000); + notification.show(Page.getCurrent()); + notification.setHtmlContentAllowed(true); + } + + public interface LoginListener extends Serializable { + void loginSuccessful(); + } +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/profile/ProfileCreationScreen.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/profile/ProfileCreationScreen.java new file mode 100644 index 0000000..717677b --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/profile/ProfileCreationScreen.java @@ -0,0 +1,127 @@ +package org.openntf.conferenceapp.ui.pages.profile; + +import java.util.HashMap; +import java.util.Map; + +import org.openntf.conferenceapp.service.AttendeeFactory; +import org.openntf.conferenceapp.ui.ConferenceUI; + +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.shared.ui.combobox.FilteringMode; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.ComboBox; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.TextField; + +public class ProfileCreationScreen extends CustomComponent implements View { + + private ConferenceUI parentUI = null; + + private FormLayout formLayout; + + private TextField email = null; + private TextField firstname = null; + private TextField lastname = null; + private TextField Twitter = null; + private ComboBox country = null; + private TextField Facebook = null; + private TextField Url = null; + private TextField Phone = null; + private TextField Profile = null; + private TextField Role = null; + + private Button submitBtn; + + + public ProfileCreationScreen(ConferenceUI conferenceUI, String userEmail) { + + this.parentUI = conferenceUI; + + System.out.println("Building ui"); + + formLayout = new FormLayout(); + formLayout.setMargin(true); + + formLayout.addComponent((email = new TextField("Email", userEmail))); + formLayout.addComponent((firstname = new TextField("Firstname"))); + formLayout.addComponent((lastname = new TextField("Lastname"))); + formLayout.addComponent((Twitter = new TextField("Twitter"))); + formLayout.addComponent((country = new ComboBox("Country"))); + formLayout.addComponent((Facebook = new TextField("Facebook"))); + formLayout.addComponent((Url = new TextField("Url"))); + formLayout.addComponent((Phone = new TextField("Phone"))); + formLayout.addComponent((Profile = new TextField("Profile"))); + formLayout.addComponent((Role = new TextField("Role"))); + + country.setInputPrompt("Select your country"); + country.addItem("Italy"); + country.addItem("Belgium"); + country.addItem("UK"); + country.setRequired(true); + country.setNewItemsAllowed(false); + country.setNullSelectionAllowed(false); + country.setFilteringMode(FilteringMode.STARTSWITH); + + email.setWidth(40, Unit.EM); + email.setRequired(true); + email.setReadOnly(true); + + firstname.setWidth(30,Unit.EM); + firstname.setRequired(true); + + lastname.setWidth(30, Unit.EM); + lastname.setRequired(true); + + Twitter.setWidth(30, Unit.EM); + country.setWidth(30, Unit.EM); + Facebook.setWidth(30, Unit.EM); + Url.setWidth(30, Unit.EM); + Phone.setWidth(30, Unit.EM); + Profile.setWidth(30, Unit.EM); + Role.setWidth(30, Unit.EM); + + formLayout.addComponent((submitBtn = new Button("Create my profile and access the conference >>>"))); + + submitBtn.addClickListener(new ClickListener() { + + @Override + public void buttonClick(ClickEvent event) { + + firstname.validate(); + + Map userProfile = new HashMap(); + + userProfile.put("Email", email.getValue()); + userProfile.put("Firstname", firstname.getValue()); + userProfile.put("Lastname", lastname.getValue()); + userProfile.put("Twitter", Twitter.getValue()); + userProfile.put("Country", country.getValue()); + userProfile.put("Facebook", Facebook.getValue()); + userProfile.put("Url", Url.getValue()); + userProfile.put("Phone", Phone.getValue()); + userProfile.put("Profile", Profile.getValue()); + userProfile.put("Role", Role.getValue()); + + AttendeeFactory.addAttendee(userProfile); + + System.out.println("Profile created"); + + parentUI.showMainView(); + } + }); + + setCompositionRoot(formLayout); + + } + + @Override + public void enter(ViewChangeEvent event) { + // TODO Auto-generated method stub + + } + +} diff --git a/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/profile/ProfileView.java b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/profile/ProfileView.java new file mode 100644 index 0000000..2d54f05 --- /dev/null +++ b/samples/ConferenceApp/src/org/openntf/conferenceapp/ui/pages/profile/ProfileView.java @@ -0,0 +1,64 @@ +package org.openntf.conferenceapp.ui.pages.profile; + +import org.openntf.conference.graph.Attendee; +import org.openntf.conferenceapp.authentication.ConferenceMembershipService; +import org.openntf.conferenceapp.authentication.CurrentUser; + +import com.vaadin.data.util.BeanItem; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.ui.CustomComponent; +import com.vaadin.ui.FormLayout; +import com.vaadin.ui.Panel; +import com.vaadin.ui.TextField; + +/** + * @author daniele.vistalli + * + * This class implements a custom component used to show a user profile. + * In case the user profile is owned by the current user then editing + * features are made available. + * + */ +public class ProfileView extends CustomComponent implements View { + + // User photo + // Email + // Twitter handle + // Name + // Lastname + + public static final String VIEW_NAME = "myprofile"; + public static final String VIEW_DESC = "My Profile"; + + BeanItem attendeeBean = null; + private TextField emailField; + + @Override + public void enter(ViewChangeEvent event) { + + System.out.println("Loading data for profile: " + CurrentUser.get()); + + Attendee myUserProfile = ConferenceMembershipService.findUserProfileByEmail(CurrentUser.get()); + + attendeeBean = new BeanItem(myUserProfile); + emailField.setPropertyDataSource(attendeeBean.getItemProperty("Email")); + + } + + public ProfileView() { + + Panel profilePanel = new Panel(); + + FormLayout profileForm = new FormLayout(); + profileForm.setMargin(true); + + profileForm.addComponent(emailField = new TextField("Identity")); + + profilePanel.setContent(profileForm); + profilePanel.setSizeFull(); + + setCompositionRoot(profilePanel); + } + +} diff --git a/samples/Connected2015World/.gitignore b/samples/Connected2015World/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/samples/Connected2015World/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/samples/Connected2015World/.project b/samples/Connected2015World/.project new file mode 100644 index 0000000..43e42ea --- /dev/null +++ b/samples/Connected2015World/.project @@ -0,0 +1,44 @@ + + + ConnectED2015World + + + org.openntf.xworlds.webapp.j2eeenabler + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.jsdt.core.jsNature + + + + plugins + 2 + D:/dev/gitroot/org.openntf.domino/domino/org.openntf.domino.updatesite/target/site/plugins + + + diff --git a/samples/CrossWorldsDemo/.classpath b/samples/CrossWorldsDemo/.classpath new file mode 100644 index 0000000..0e56e43 --- /dev/null +++ b/samples/CrossWorldsDemo/.classpath @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/CrossWorldsDemo/.factorypath b/samples/CrossWorldsDemo/.factorypath new file mode 100644 index 0000000..f0013fa --- /dev/null +++ b/samples/CrossWorldsDemo/.factorypath @@ -0,0 +1,4 @@ + + + + diff --git a/samples/CrossWorldsDemo/.gitignore b/samples/CrossWorldsDemo/.gitignore new file mode 100644 index 0000000..9ed481c --- /dev/null +++ b/samples/CrossWorldsDemo/.gitignore @@ -0,0 +1,2 @@ +/.apt_generated/ +/target/ diff --git a/samples/CrossWorldsDemo/.project b/samples/CrossWorldsDemo/.project new file mode 100644 index 0000000..27fe988 --- /dev/null +++ b/samples/CrossWorldsDemo/.project @@ -0,0 +1,42 @@ + + + CrossWorldsDemo + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.jem.workbench.JavaEMFNature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/samples/CrossWorldsDemo/.settings/.jsdtscope b/samples/CrossWorldsDemo/.settings/.jsdtscope new file mode 100644 index 0000000..3a28de0 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/.jsdtscope @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/samples/CrossWorldsDemo/.settings/com.ibm.ws.st.shared.library.ref b/samples/CrossWorldsDemo/.settings/com.ibm.ws.st.shared.library.ref new file mode 100644 index 0000000..d24c1c1 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/com.ibm.ws.st.shared.library.ref @@ -0,0 +1,2 @@ +#Sun Dec 28 23:03:14 CET 2014 +com.ibm.ws.st.jee.shared.library.ref.id= diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.jdt.apt.core.prefs b/samples/CrossWorldsDemo/.settings/org.eclipse.jdt.apt.core.prefs new file mode 100644 index 0000000..6b471d7 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.jdt.apt.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.apt.aptEnabled=true +org.eclipse.jdt.apt.reconcileEnabled=true diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.jdt.core.prefs b/samples/CrossWorldsDemo/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..aa3d9fc --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,14 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.processAnnotations=enabled +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.ltk.core.refactoring.prefs b/samples/CrossWorldsDemo/.settings/org.eclipse.ltk.core.refactoring.prefs new file mode 100644 index 0000000..b196c64 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.ltk.core.refactoring.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.m2e.core.prefs b/samples/CrossWorldsDemo/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.m2e.wtp.prefs b/samples/CrossWorldsDemo/.settings/org.eclipse.m2e.wtp.prefs new file mode 100644 index 0000000..ef86089 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.m2e.wtp.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.m2e.wtp.enabledProjectSpecificPrefs=false diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.component b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..e586424 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.component @@ -0,0 +1,12 @@ + + + + + + + uses + + + + + diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml new file mode 100644 index 0000000..3daed77 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.project.facet.core.prefs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.project.facet.core.xml b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..95523b5 --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.wst.jsdt.ui.superType.container b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..3bd5d0a --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.baseBrowserLibrary \ No newline at end of file diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.wst.jsdt.ui.superType.name b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..05bd71b --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Window \ No newline at end of file diff --git a/samples/CrossWorldsDemo/.settings/org.eclipse.wst.validation.prefs b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..04cad8c --- /dev/null +++ b/samples/CrossWorldsDemo/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,2 @@ +disabled=06target +eclipse.preferences.version=1 diff --git a/samples/CrossWorldsDemo/WebContent/.gitignore b/samples/CrossWorldsDemo/WebContent/.gitignore new file mode 100644 index 0000000..3385916 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/.gitignore @@ -0,0 +1 @@ +/META-INF/ diff --git a/samples/CrossWorldsDemo/WebContent/META-INF/MANIFEST.MF b/samples/CrossWorldsDemo/WebContent/META-INF/MANIFEST.MF new file mode 100644 index 0000000..db42e15 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Built-By: Paul Stephen Withers +Build-Jdk: 1.8.0_66 +Created-By: Maven Integration for Eclipse + diff --git a/samples/CrossWorldsDemo/WebContent/META-INF/maven/org.openntf.xworlds.samples/.gitignore b/samples/CrossWorldsDemo/WebContent/META-INF/maven/org.openntf.xworlds.samples/.gitignore new file mode 100644 index 0000000..1b58f96 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/META-INF/maven/org.openntf.xworlds.samples/.gitignore @@ -0,0 +1 @@ +/CrossWorldsDemo/ diff --git a/samples/CrossWorldsDemo/WebContent/WEB-INF/.gitignore b/samples/CrossWorldsDemo/WebContent/WEB-INF/.gitignore new file mode 100644 index 0000000..840e7d3 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/WEB-INF/.gitignore @@ -0,0 +1 @@ +/classes/ diff --git a/samples/CrossWorldsDemo/WebContent/WEB-INF/web.xml b/samples/CrossWorldsDemo/WebContent/WEB-INF/web.xml new file mode 100644 index 0000000..663f164 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/WEB-INF/web.xml @@ -0,0 +1,44 @@ + + + CrossWorldsDemo + + + JAX-RS Tools Generated - Do not modify + JAX-RS Servlet + com.ibm.websphere.jaxrs.server.IBMRestServlet + 1 + true + false + + + + index.html + index.htm + index.jsp + default.html + default.htm + default.jsp + + + + This is the description for the sample servlet + + Domino Rest Application + + icons/small.gif + icons/small.gif + + org.openntf.xworlds.demo.CrossWorldsRestSampleApplication + + + + org.openntf.xworlds.demo.CrossWorldsRestSampleApplication + + /domrest/* + /demo/* + + + org.openntf.crossworlds.appsignername + CN=CrossWorlds/O=OpenNTF.org + + \ No newline at end of file diff --git a/samples/CrossWorldsDemo/WebContent/css/bs-callout.css b/samples/CrossWorldsDemo/WebContent/css/bs-callout.css new file mode 100644 index 0000000..1d64c74 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/css/bs-callout.css @@ -0,0 +1,56 @@ +.bs-callout { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; +} +.bs-callout h4 { + margin-top: 0; + margin-bottom: 5px; +} +.bs-callout p:last-child { + margin-bottom: 0; +} +.bs-callout code { + border-radius: 3px; +} +.bs-callout+.bs-callout { + margin-top: -5px; +} +.bs-callout-default { + border-left-color: #777; +} +.bs-callout-default h4 { + color: #777; +} +.bs-callout-primary { + border-left-color: #428bca; +} +.bs-callout-primary h4 { + color: #428bca; +} +.bs-callout-success { + border-left-color: #5cb85c; +} +.bs-callout-success h4 { + color: #5cb85c; +} +.bs-callout-danger { + border-left-color: #d9534f; +} +.bs-callout-danger h4 { + color: #d9534f; +} +.bs-callout-warning { + border-left-color: #f0ad4e; +} +.bs-callout-warning h4 { + color: #f0ad4e; +} +.bs-callout-info { + border-left-color: #5bc0de; +} +.bs-callout-info h4 { + color: #5bc0de; +} \ No newline at end of file diff --git a/samples/CrossWorldsDemo/WebContent/images/favicon.ico b/samples/CrossWorldsDemo/WebContent/images/favicon.ico new file mode 100644 index 0000000..140123c Binary files /dev/null and b/samples/CrossWorldsDemo/WebContent/images/favicon.ico differ diff --git a/samples/CrossWorldsDemo/WebContent/index.jsp b/samples/CrossWorldsDemo/WebContent/index.jsp new file mode 100644 index 0000000..1e85e3a --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/index.jsp @@ -0,0 +1,93 @@ +<%@page import="org.openntf.domino.utils.Factory.SessionType"%> +<%@page import="org.openntf.domino.utils.Factory"%> + + + + + + + CrossWorlds Demo + + + + + + + + + + + + + + + + + +
+
+

Hello, CrossWorlds!

+

This application shows you the possibilities that the OpenNTF Domino API and WAS Liberty bring to Domino developers

+ +
+
+ +
+ +
+
+

Why

+

XPages brought IBM Domino up to date for web development. XPages are intended to bring Domino Applications.

+

But what happens if we're looking to use the power of domino for other kind of applications ?

+

XPages just is not the right tool, we felt J2EE 6.0+ with Domino could be a wedding made in heaven. CrossWorlds is just about this

+

Why CrossWorlds »

+
+
+

What

+

IBM has been including for a long time a license of WebSphere in all Domino licenses.

+

We took advantage of this to create an easy-to-setup, easy-to-use application server exploiting IBM WebSphere Application Server Liberty on top of IBM Domino

+

CrossWorlds is a lightweight, modern, extensible J2EE application server embedding the full power of Domino.

+

Thanks to ODA we've Domino native performance inside a full J2EE stack. The best of both worlds.

+

What's CrossWorlds »

+
+
+

Play

+

This sample application is built on CrossWorlds to show you how this works for you.

+

Use the embedded code editor to write code using the full domino API and get the results fast

+

This app will evolve to become a full API / Explorer and eventually a Web IDE

+

Our mission is to bring Domino developers and Java developers to easily exploit the advantages of J2EE and Domino together.

+

Play with CrossWorlds »

+
+
+ +
+ +
+

© TBD/Factor-y/OpenNTF 2014

+
+
+ + + + + + + \ No newline at end of file diff --git a/samples/CrossWorldsDemo/WebContent/play.jsp b/samples/CrossWorldsDemo/WebContent/play.jsp new file mode 100644 index 0000000..dddefc5 --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/play.jsp @@ -0,0 +1,197 @@ +<%@page import="org.openntf.domino.utils.Factory.SessionType"%> +<%@page import="org.openntf.domino.utils.Factory"%> + + + + + + + CrossWorlds Demo + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

Play with CrossWorlds

+
+
+ + +
+ +
+ +
+

Success

+

+ Output:
+
+

+

+ Return value:
+ + +

+
+
+

Failure

+

+ Your script failed with error: +
+
+ Stack trace:
+ +

+
+ +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/samples/CrossWorldsDemo/WebContent/setDeveloperIdentity.jsp b/samples/CrossWorldsDemo/WebContent/setDeveloperIdentity.jsp new file mode 100644 index 0000000..1e2838d --- /dev/null +++ b/samples/CrossWorldsDemo/WebContent/setDeveloperIdentity.jsp @@ -0,0 +1,32 @@ +<%@ page language="java" contentType="text/html; charset=ISO-8859-1" + pageEncoding="ISO-8859-1" session="true" %> + + + + +CrossWorlds devloper mode - Setting session identity + + +<% + + // Invalidate + session.invalidate(); + // Get new session + session = request.getSession(true); + // Override identity + String newIdentity = request.getParameter("fullname"); + if (newIdentity == null) { + session.removeAttribute("xworlds.request.username"); + } else { + session.setAttribute("xworlds.request.username", newIdentity); + } + +%> +New user identity set to <%= session.getAttribute("xworlds.request.username") %> +

+
+ "> + +
+ + \ No newline at end of file diff --git a/samples/CrossWorldsDemo/pom.xml b/samples/CrossWorldsDemo/pom.xml new file mode 100644 index 0000000..100fbc5 --- /dev/null +++ b/samples/CrossWorldsDemo/pom.xml @@ -0,0 +1,79 @@ + + 4.0.0 + org.openntf.xworlds.samples + CrossWorldsDemo + 0.0.2-SNAPSHOT + war + CrossWorlds sampler application & developer tools + + + com.ibm.tools.target + was-liberty + LATEST + pom + provided + + + javax.faces-api + javax.faces + + + + + org.codehaus.groovy + groovy-all + 1.8.9 + + + org.openntf.xworlds.webapp + j2eeenabler + 0.0.1-SNAPSHOT + + + org.webjars + codemirror + 4.11 + + + org.webjars + bootstrap + 3.3.2 + + + org.webjars + jquery + 1.11.2 + + + + src + + + src + + **/*.java + + + + + + maven-war-plugin + 2.4 + + WebContent + false + + + + maven-compiler-plugin + 3.1 + + 1.6 + 1.6 + + + + + https://github.com/Factor-y/CrossWorlds + December 2014 + \ No newline at end of file diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/CrossWorldsRestSampleApplication.java b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/CrossWorldsRestSampleApplication.java new file mode 100644 index 0000000..d57caf1 --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/CrossWorldsRestSampleApplication.java @@ -0,0 +1,28 @@ +package org.openntf.xworlds.demo; + +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.core.Application; + +public class CrossWorldsRestSampleApplication extends Application { + + @Override + public Set> getClasses() { + Set> classes = new HashSet>(); + classes.add(Server.class); + classes.add(TestForPerformance.class); + return classes; + } + + @Override + public Set getSingletons() { + Set classes = new HashSet(); + classes.add(new PlayWithCrossWorlds()); + return classes; + } + + + + +} diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/PlayWithCrossWorlds.java b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/PlayWithCrossWorlds.java new file mode 100644 index 0000000..9fc57c4 --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/PlayWithCrossWorlds.java @@ -0,0 +1,86 @@ +package org.openntf.xworlds.demo; + +import groovy.lang.Binding; +import groovy.lang.GroovyShell; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Map; + +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.codehaus.groovy.control.CompilerConfiguration; + +@Path("/play") +public class PlayWithCrossWorlds { + + private CompilerConfiguration compilerConfig = null; + + public PlayWithCrossWorlds() { + compilerConfig = new CompilerConfiguration(); + + compilerConfig.setDebug(true); + compilerConfig.setVerbose(true); + + } + + @Path("/runscript") + @POST + @Produces(MediaType.APPLICATION_JSON) + public Response runScript( + @FormParam("scriptbody") String scriptBody + ) { + + StringWriter sw = new StringWriter(); + + // call groovy expressions from Java code + Binding binding = new Binding(); + binding.setVariable("out", new PrintWriter(sw)); + + Map result = new HashMap(); + + Object value = null; + try { + + GroovyShell shell = new GroovyShell(binding, compilerConfig); + value = shell.evaluate(scriptBody); + + } catch (Exception e) { + result.put("errormessage", e.getMessage()); + sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + result.put("exceptionStack", sw.toString()); + return Response + .status(Status.INTERNAL_SERVER_ERROR) + .type(MediaType.APPLICATION_JSON_TYPE) + .entity(result) + .build(); + } catch (Error e) { + result.put("errormessage", e.getMessage()); + sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + result.put("exceptionStack", sw.toString()); + return Response + .status(Status.INTERNAL_SERVER_ERROR) + .type(MediaType.APPLICATION_JSON_TYPE) + .entity(result) + .build(); + } + + + result.put("value", value.toString()); + result.put("out", sw.toString()); + + return Response + .ok(result, MediaType.APPLICATION_JSON_TYPE) + .build(); + } + +} diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/Server.java b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/Server.java new file mode 100644 index 0000000..c93bded --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/Server.java @@ -0,0 +1,135 @@ +package org.openntf.xworlds.demo; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.openntf.domino.Agent; +import org.openntf.domino.Database; +import org.openntf.domino.DbDirectory; +import org.openntf.domino.Session; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +import com.ibm.domino.napi.c.NotesUtil; +import com.ibm.domino.napi.c.xsp.XSPNative; + +@Path("/server") +public class Server { + + class DatabaseBean { + private String apiPath; + private String replicaid; + private String title; + + public DatabaseBean(String apiPath, + String title, + String replicaId) { + this.apiPath = apiPath; + this.title = title; + this.replicaid = replicaId; + } + + public String getApiPath() { + return apiPath; + } + + public void setApiPath(String apiPath) { + this.apiPath = apiPath; + } + + public String getReplicaid() { + return replicaid; + } + + public void setReplicaid(String replicaid) { + this.replicaid = replicaid; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + + } + + @GET + @Path("/dbdirectory") + @Produces(MediaType.APPLICATION_JSON) + public Response getDbDirectory(@QueryParam("servername") String ServerName) { + + Session s = Factory.getSession(SessionType.CURRENT); + + DbDirectory dbdir = s.getDbDirectory(ServerName); + + Iterator i = dbdir.iterator(); + + List dbs = new ArrayList(); + + while (i.hasNext()) { + Database db = i.next(); + dbs.add(new DatabaseBean(db.getApiPath(), db.getTitle(), db.getReplicaID())); + } + + return Response.status(200).type(MediaType.APPLICATION_JSON).entity(dbs).build(); + + } + + @GET + @Path("/runas") + @Produces(MediaType.APPLICATION_JSON) + public Response runAsUser(@QueryParam("username") String userName) { + + if (checkNotNull(userName,"username parameter must be specified") == null) { + return Response.status(Status.INTERNAL_SERVER_ERROR).entity("username must be specified").build(); + } + + lotus.domino.Session rawSession = null; + + try { + String runAs = userName; + long userHandle = NotesUtil.createUserNameList(runAs); + rawSession = XSPNative.createXPageSessionExt(runAs, userHandle, false, true, true); + + return Response.ok().entity(rawSession.getEffectiveUserName()).build(); + } catch (Exception e) { + e.printStackTrace(); + } + + return Response.status(Status.INTERNAL_SERVER_ERROR).build(); + + } + + @GET + @Path("/runagent") + @Produces(MediaType.APPLICATION_JSON) + public Response getDbDirectory(@QueryParam("servername") String serverName, + @QueryParam("dbname") String dbname, @QueryParam("agentname") String agentName) { + + Session s = Factory.getSession(SessionType.CURRENT); + + Database db = s.getDatabase(serverName, dbname); + + Agent agent = db.getAgent(agentName); + + agent.run(); + + return Response.status(200).type(MediaType.APPLICATION_JSON).entity(agent.getLastRun().toString()).build(); + + } + +} diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/TestForPerformance.java b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/TestForPerformance.java new file mode 100644 index 0000000..69026e6 --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/TestForPerformance.java @@ -0,0 +1,73 @@ +package org.openntf.xworlds.demo; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openntf.domino.Database; +import org.openntf.domino.Document; +import org.openntf.domino.Item; +import org.openntf.domino.Session; +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; + +@Path("/test") +public class TestForPerformance { + + @GET + public Response testCheck() { + return Response.status(200).entity("OK - Test").build(); + } + + @GET + @Path("/countdocs") + @Produces(MediaType.APPLICATION_JSON) + public Response countDocumens() { + Session s = Factory.getSession(SessionType.CURRENT); + + return Response.status(HttpServletResponse.SC_NOT_IMPLEMENTED).build(); + } + + @POST + @Path("/makedocs") + @Produces(MediaType.APPLICATION_JSON) + public Response doMakeDocuments( + @QueryParam("dbname") @DefaultValue("crossworlds\\test.nsf") String dbname, + @QueryParam("count") @DefaultValue("1") int docsToCreate) { + + System.out.println("Servlet thread: " + Thread.currentThread().getId()); + + Session s = Factory.getSession(SessionType.SIGNER); + + Database db = s.getDatabase(dbname); + + long start = System.currentTimeMillis(); + + int c = 0; + for (; c < docsToCreate; c++) { + + Document doc = db.createDocument(); + + doc.replaceItemValue("Form", "fUserName",false); + doc.replaceItemValue("Firstname", "A-Cross " + (Math.random() * 1000),false); + doc.replaceItemValue("Lastname", "A-Worlds",false); + + doc.save(); + + } + + System.out.println("Millisecs for running: " + + (System.currentTimeMillis() - start) + " for " + c + + " documents."); + + return Response.status(200).entity(c).build(); + + } + +} diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/TestConcurrentDocCreation.java b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/TestConcurrentDocCreation.java new file mode 100644 index 0000000..fbf2351 --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/TestConcurrentDocCreation.java @@ -0,0 +1,65 @@ +package org.openntf.xworlds.demo.testclient; + +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +public class TestConcurrentDocCreation { + + class Creator implements Runnable { + + private int _count = 10; + + public Creator(int count) { + _count = count; + } + + @Override + public void run() { + + try { + URL maker = new URL("http://localhost:9080/CrossWorldsDemo/domrest/test/makedocs?count=" + _count); + + long start = System.currentTimeMillis(); + System.out.println("Thread " + Thread.currentThread().getId() + " for " + _count + " documents starting"); + + HttpURLConnection uc = (HttpURLConnection) maker.openConnection(); + uc.setRequestMethod("POST"); + uc.connect(); + + System.out.println("Thread " + Thread.currentThread().getId() + " for " + _count + " documents = results" + uc.getResponseCode() + " in " + (System.currentTimeMillis() - start) + " millisec"); + + + } catch (IOException e) { + + } + } + + } + + public static void main(String[] args) throws MalformedURLException { + + TestConcurrentDocCreation tester = new TestConcurrentDocCreation(); + tester.perform(); + + } + + private void perform() { + List Ts = new ArrayList(); + + int threads = 5; + int docsPerThread = 1000; + + for (int i = 0; i < threads; i++) { + Ts.add(new Thread(new Creator(docsPerThread))); + } + + for (Thread thread : Ts) { + thread.start(); + } + } + +} diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/TestGroovyScript.java b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/TestGroovyScript.java new file mode 100644 index 0000000..0624c19 --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/TestGroovyScript.java @@ -0,0 +1,39 @@ +package org.openntf.xworlds.demo.testclient; + +import java.io.InputStream; +import java.io.InputStreamReader; + +import lotus.domino.NotesThread; + +import org.openntf.domino.utils.Factory; + +import groovy.lang.GroovyShell; + +public class TestGroovyScript { + + public static void main(String[] args) throws InterruptedException { + + Factory.startup(); + + Thread.sleep(3000); + + Factory.initThread(Factory.STRICT_THREAD_CONFIG); + NotesThread.sinitThread(); + + GroovyShell gs = new GroovyShell(); + +// gs.evaluate(in) + + InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/openntf/xworlds/demo/testclient/testscript.groovy"); + + System.out.println(is); + gs.evaluate(new InputStreamReader(is)); + + NotesThread.stermThread(); + Factory.termThread(); + Factory.shutdown(); + + } + + +} diff --git a/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/testscript.groovy b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/testscript.groovy new file mode 100644 index 0000000..c705465 --- /dev/null +++ b/samples/CrossWorldsDemo/src/org/openntf/xworlds/demo/testclient/testscript.groovy @@ -0,0 +1,20 @@ +System.out.println("Hello World"); + +import org.openntf.domino.utils.Factory; +import org.openntf.domino.utils.Factory.SessionType; +import org.openntf.domino.Session; +import org.openntf.domino.Database; +import org.openntf.domino.Document; + +Session s = Factory.getSession(SessionType.NATIVE); + +def db = s.getDatabase("crossworlds/demo.nsf") + +System.out.println(db.title); +System.out.println(db.filePath); + +def doc = db.createDocument(); + +doc.replaceItemValue("form","test"); + +// doc.save(true,false); diff --git a/samples/README.md b/samples/README.md new file mode 100644 index 0000000..74b5835 --- /dev/null +++ b/samples/README.md @@ -0,0 +1,5 @@ +# Samples for CrossWorlds + +This folder contains "Sample" projects built to showcase how applications can be built and run in CrossWrolds + +Every applications contains information on how to build and use it.