use of org.openntf.nsfodp.commons.odp.notesapi.NotesAPI in project org.openntf.nsfodp by OpenNTF.
the class ODPCompilerServlet method doPost.
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Principal user = req.getUserPrincipal();
resp.setBufferSize(0);
resp.setStatus(HttpServletResponse.SC_OK);
ServletOutputStream os = resp.getOutputStream();
Set<Path> cleanup = new HashSet<>();
try {
if (!ALLOW_ANONYMOUS && "Anonymous".equalsIgnoreCase(user.getName())) {
// $NON-NLS-1$
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// $NON-NLS-1$
resp.setContentType("text/plain");
os.println(Messages.ODPCompilerServlet_anonymousDisallowed);
return;
}
// Developer's note: multipart/form-data with files broken out would be nice,
// but Domino as of 9.0.1FP10 behaves poorly with them; for now, it's safer
// to use a combined ZIP and pass options in headers
String contentType = req.getContentType();
if (!"application/zip".equals(contentType)) {
// $NON-NLS-1$
throw new IllegalArgumentException(Messages.ODPCompilerServlet_contentMustBeZip);
}
// $NON-NLS-1$ //$NON-NLS-2$
Path packageFile = Files.createTempFile(NSFODPUtil.getTempDirectory(), "package", ".zip");
cleanup.add(packageFile);
try (InputStream reqInputStream = req.getInputStream()) {
Files.copy(reqInputStream, packageFile, StandardCopyOption.REPLACE_EXISTING);
}
// Look for an ODP item
Path odpZip = null;
List<Path> siteZips = new ArrayList<>();
List<Path> classPathJars = new ArrayList<>();
try (ZipFile packageZip = new ZipFile(packageFile.toFile(), StandardCharsets.UTF_8)) {
// $NON-NLS-1$
ZipEntry odpEntry = packageZip.getEntry("odp.zip");
if (odpEntry == null) {
// Then the package is itself the ODP
odpZip = packageFile;
} else {
// Then extract the ODP
// $NON-NLS-1$ //$NON-NLS-2$
odpZip = Files.createTempFile(NSFODPUtil.getTempDirectory(), "odp", ".zip");
cleanup.add(odpZip);
try (InputStream odpIs = packageZip.getInputStream(odpEntry)) {
Files.copy(odpIs, odpZip, StandardCopyOption.REPLACE_EXISTING);
}
// Look for any embedded update sites and classpath entries
packageZip.stream().forEach(entry -> {
try {
if (SITE_ZIP_PATTERN.matcher(entry.getName()).matches()) {
// Then add it as an update site
// $NON-NLS-1$ //$NON-NLS-2$
Path siteZip = Files.createTempFile(NSFODPUtil.getTempDirectory(), "site", ".zip");
cleanup.add(siteZip);
try (InputStream siteIs = packageZip.getInputStream(entry)) {
Files.copy(siteIs, siteZip, StandardCopyOption.REPLACE_EXISTING);
}
siteZips.add(siteZip);
} else if (entry.getName().startsWith("classpath/")) {
// $NON-NLS-1$
// Then add it as an individual JAR
// $NON-NLS-1$ //$NON-NLS-2$
Path cpJar = Files.createTempFile(NSFODPUtil.getTempDirectory(), "classpathJar", ".jar");
cleanup.add(cpJar);
try (InputStream jarIs = packageZip.getInputStream(entry)) {
Files.copy(jarIs, cpJar, StandardCopyOption.REPLACE_EXISTING);
}
classPathJars.add(cpJar);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
});
}
}
IProgressMonitor mon = new LineDelimitedJsonProgressMonitor(os);
Path nsf;
try (FileSystem fs = NSFODPUtil.openZipPath(odpZip)) {
// $NON-NLS-1$
Path odpFile = fs.getPath("/");
OnDiskProject odp = new OnDiskProject(odpFile);
ODPCompiler compiler = new ODPCompiler(ODPCompilerActivator.instance.getBundle().getBundleContext(), odp, mon);
// See if the client requested a specific compiler level
String compilerLevel = req.getHeader(NSFODPConstants.HEADER_COMPILER_LEVEL);
if (StringUtil.isNotEmpty(compilerLevel)) {
compiler.setCompilerLevel(compilerLevel);
}
String appendTimestamp = req.getHeader(NSFODPConstants.HEADER_APPEND_TIMESTAMP);
if ("true".equals(appendTimestamp)) {
// $NON-NLS-1$
compiler.setAppendTimestampToTitle(true);
}
String templateName = req.getHeader(NSFODPConstants.HEADER_TEMPLATE_NAME);
if (StringUtil.isNotEmpty(templateName)) {
compiler.setTemplateName(templateName);
String templateVersion = req.getHeader(NSFODPConstants.HEADER_TEMPLATE_VERSION);
if (StringUtil.isNotEmpty(templateVersion)) {
compiler.setTemplateVersion(templateVersion);
}
}
String setXspOptions = req.getHeader(NSFODPConstants.HEADER_SET_PRODUCTION_XSP);
if ("true".equals(setXspOptions)) {
// $NON-NLS-1$
compiler.setSetProductionXspOptions(true);
}
String odsRelease = req.getHeader(NSFODPConstants.HEADER_ODS_RELEASE);
if (StringUtil.isNotEmpty(odsRelease)) {
compiler.setOdsRelease(odsRelease);
}
String compileBasicLs = req.getHeader(NSFODPConstants.HEADER_COMPILE_BASICLS);
if ("true".equals(compileBasicLs)) {
// $NON-NLS-1$
compiler.setCompileBasicElementLotusScript(true);
}
if (siteZips != null && !siteZips.isEmpty()) {
for (Path siteZip : siteZips) {
Path siteFile = NSFODPUtil.expandZip(siteZip);
cleanup.add(siteFile);
UpdateSite updateSite = new FilesystemUpdateSite(siteFile);
compiler.addUpdateSite(updateSite);
}
}
classPathJars.forEach(compiler::addClassPathEntry);
nsf = this.exec.submit(() -> {
Path result = compiler.compile();
mon.done();
return result;
}).get();
}
// Now stream the NSF
cleanup.add(nsf);
try (OutputStream gzos = new GZIPOutputStream(os)) {
Files.copy(nsf, gzos);
}
resp.flushBuffer();
// Delete the NSF via the Notes API
try (NotesAPI api = NotesAPI.get()) {
api.deleteDatabase(nsf.toString());
}
} catch (Throwable e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(baos);
e.printStackTrace(out);
out.flush();
os.println(LineDelimitedJsonProgressMonitor.message(// $NON-NLS-1$ //$NON-NLS-2$
"type", // $NON-NLS-1$ //$NON-NLS-2$
"error", // $NON-NLS-1$
"stackTrace", // $NON-NLS-1$
baos.toString()));
} finally {
NSFODPUtil.deltree(cleanup);
}
}
use of org.openntf.nsfodp.commons.odp.notesapi.NotesAPI in project org.openntf.nsfodp by OpenNTF.
the class ExporterApplication method start.
@Override
public Object start(IApplicationContext context) throws Exception {
String notesIni = System.getenv(NSFODPConstants.PROP_NOTESINI);
if (notesIni != null && !notesIni.isEmpty()) {
// $NON-NLS-1$
String execDir = System.getenv("Notes_ExecDirectory");
try (NotesAPI api = NotesAPI.get()) {
// $NON-NLS-1$
api.NotesInitExtended(execDir, "=" + notesIni);
}
}
String databasePath = System.getenv(NSFODPConstants.PROP_EXPORTER_DATABASE_PATH);
if (databasePath == null) {
throw new IllegalArgumentException(MessageFormat.format(Messages.ExporterApplication_dbPathCannotBeEmpty, NSFODPConstants.PROP_EXPORTER_DATABASE_PATH));
}
Path odpDir = Paths.get(System.getenv(NSFODPConstants.PROP_OUTPUTFILE));
// $NON-NLS-1$
boolean binaryDxl = "true".equals(System.getenv(NSFODPConstants.PROP_EXPORTER_BINARY_DXL));
// $NON-NLS-1$
boolean swiperFilter = "true".equals(System.getenv(NSFODPConstants.PROP_EXPORTER_SWIPER_FILTER));
// $NON-NLS-1$
boolean richTextAsItemData = "true".equals(System.getenv(NSFODPConstants.PROP_RICH_TEXT_AS_ITEM_DATA));
String projectName = System.getenv(NSFODPConstants.PROP_PROJECT_NAME);
NotesThread runner = new NotesThread(() -> {
try (NotesAPI session = NotesAPI.get()) {
try (NDatabase database = session.openDatabase(databasePath)) {
ODPExporter exporter = new ODPExporter(database);
exporter.setBinaryDxl(binaryDxl);
exporter.setSwiperFilter(swiperFilter);
exporter.setRichTextAsItemData(richTextAsItemData);
exporter.setProjectName(projectName);
Path result = exporter.export();
// $NON-NLS-1$
Path eclipseProject = odpDir.resolve(".project");
if (Files.exists(eclipseProject)) {
// $NON-NLS-1$ //$NON-NLS-2$
Path tempPath = Files.createTempFile("nsfodp", ".project");
Files.move(eclipseProject, tempPath, StandardCopyOption.REPLACE_EXISTING);
eclipseProject = tempPath;
} else {
eclipseProject = null;
}
if (Files.exists(odpDir)) {
NSFODPUtil.deltree(Collections.singleton(odpDir));
}
Files.createDirectories(odpDir);
NSFODPUtil.moveDirectory(result, odpDir);
if (eclipseProject != null) {
// $NON-NLS-1$
Files.move(eclipseProject, odpDir.resolve(".project"), StandardCopyOption.REPLACE_EXISTING);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
});
runner.run();
runner.join();
return EXIT_OK;
}
use of org.openntf.nsfodp.commons.odp.notesapi.NotesAPI in project org.openntf.nsfodp by OpenNTF.
the class ODPCompiler method compile.
/**
* Runs the compilation process:
*
* <ol>
* <li>Installs all bundles from the provided update sites</li>
* <li>Initializes plugin contributions from installed bundles</li>
* <li>Compiles all XPage artifacts</li>
* <li>Constructs the NSF from the on-disk project</li>
* <li>Uninstalls any installed bundles</li>
* </ol>
*
* @param cl the base {@link ClassLoader} to use during compilation
* @return a {@link Path} representing the created database
* @throws Exception if there is a problem compiling any component
* @since 1.0.0
*/
public synchronized Path compile(ClassLoader cl) throws Exception {
Collection<Bundle> bundles = installBundles();
JavaSourceClassLoader classLoader = null;
Set<Path> cleanup = new HashSet<>();
try {
boolean hasXPages = odp.hasXPagesElements();
if (hasXPages) {
initRegistry();
Collection<String> dependencies = buildDependenciesCollection(cleanup);
dependencies.addAll(ODPUtil.expandRequiredBundles(bundleContext, odp.getRequiredBundles()));
// Add any Jars from the ODP
for (Path jar : odp.getJars()) {
// If the path is inside a JAR, extract it
if ("jar".equals(jar.toUri().getScheme())) {
// $NON-NLS-1$
// $NON-NLS-1$
Path tempJar = Files.createTempFile(NSFODPUtil.getTempDirectory(), jar.getFileName().toString(), ".jar");
cleanup.add(tempJar);
Files.copy(jar, tempJar, StandardCopyOption.REPLACE_EXISTING);
// $NON-NLS-1$
dependencies.add("jar:" + tempJar.toUri());
} else {
// $NON-NLS-1$
dependencies.add("jar:" + jar.toUri());
}
}
String[] classPath = dependencies.toArray(new String[dependencies.size()]);
List<String> options = Stream.concat(compilerOptions.stream(), // $NON-NLS-1$ //$NON-NLS-2$
Stream.of("-source", compilerLevel, "-target", compilerLevel)).collect(Collectors.toList());
classLoader = new JavaSourceClassLoader(cl, options, classPath);
// Bar loading of different-version SSJS classes from ndext
// $NON-NLS-1$
classLoader.getJavaFileManager().setNonDelegatingPackages(Arrays.asList("com.ibm.jscript"));
// Compile Java classes
compileJavaSources(classLoader);
compileCustomControls(classLoader);
compileXPages(classLoader);
}
try (NotesAPI session = NotesAPI.get()) {
Path file = createDatabase(session);
try (NDatabase database = session.openDatabase("", file.toAbsolutePath().toString())) {
// $NON-NLS-1$
try (NDXLImporter importer = session.createDXLImporter()) {
importDbProperties(importer, database);
importEarlyBasicElements(importer, database);
importLotusScriptLibraries(importer, database);
importBasicElements(importer, database);
importFileResources(importer, database);
importDbScript(importer, database);
if (hasXPages) {
Set<String> compiledClassNames = new HashSet<>(classLoader.getCompiledClassNames());
importCustomControls(importer, database, classLoader, compiledClassNames);
importXPages(importer, database, classLoader, compiledClassNames);
importJavaElements(importer, database, classLoader, compiledClassNames);
}
// Append a timestamp if requested
if (this.isAppendTimestampToTitle()) {
// $NON-NLS-1$
database.setTitle(database.getTitle() + " - " + TIMESTAMP.get().format(new Date()));
}
// Set the template info if requested
String templateName = this.getTemplateName();
if (StringUtil.isNotEmpty(templateName)) {
// $NON-NLS-1$
int noteId = database.getSharedFieldNoteID("$TemplateBuild");
NNote doc;
if (noteId != 0) {
doc = database.getNoteByID(noteId);
} else {
// Import an empty one
try (InputStream is = ODPCompiler.class.getResourceAsStream("/dxl/TemplateBuild.xml")) {
// $NON-NLS-1$
// $NON-NLS-1$
String dxl = StreamUtil.readString(is, "UTF-8");
// $NON-NLS-1$
List<Integer> ids = importDxl(importer, dxl, database, "$TemplateBuild blank field");
doc = database.getNoteByID(ids.get(0));
}
}
String version = this.getTemplateVersion();
if (StringUtil.isNotEmpty(version)) {
// $NON-NLS-1$
doc.set("$TemplateBuild", version);
}
// $NON-NLS-1$
doc.set("$TemplateBuildName", templateName);
// $NON-NLS-1$
doc.set("$TemplateBuildDate", new Date());
doc.save();
}
}
}
return file;
}
} catch (JavaCompilerException e) {
StringWriter o = new StringWriter();
PrintWriter errOut = new PrintWriter(o);
e.printExtraInformation(errOut);
throw new RuntimeException(MessageFormat.format(Messages.ODPCompiler_javaCompilationFailed, o), e);
} finally {
uninstallBundles(bundles);
if (classLoader != null) {
classLoader.close();
}
NSFODPUtil.deltree(cleanup);
}
}
use of org.openntf.nsfodp.commons.odp.notesapi.NotesAPI in project org.openntf.nsfodp by OpenNTF.
the class CompilerApplication method start.
@Override
public Object start(IApplicationContext context) throws Exception {
String notesIni = System.getenv(NSFODPConstants.PROP_NOTESINI);
if (notesIni != null && !notesIni.isEmpty()) {
// $NON-NLS-1$
String execDir = System.getenv("Notes_ExecDirectory");
try (NotesAPI api = NotesAPI.get()) {
// $NON-NLS-1$
api.NotesInitExtended(execDir, "=" + notesIni);
}
}
try {
NotesThread.sinitThread();
} catch (Exception e) {
// Known exception message during Notes initialization - error code 0x0102
if (String.valueOf(e.getMessage()).endsWith(" - err 258")) {
// $NON-NLS-1$
throw new Exception("Encountered Notes exception ERR_PROTECTED (0x0102): Cannot write or create file (file or disk is read-only)");
}
throw e;
}
try {
Path odpDirectory = toPath(System.getenv(NSFODPConstants.PROP_ODPDIRECTORY));
List<Path> updateSites = toPaths(System.getenv(NSFODPConstants.PROP_UPDATESITE));
Path outputFile = toPath(System.getenv(NSFODPConstants.PROP_OUTPUTFILE));
IProgressMonitor mon = new PrintStreamProgressMonitor(System.out);
OnDiskProject odp = new OnDiskProject(odpDirectory);
ODPCompiler compiler = new ODPCompiler(ODPCompilerActivator.instance.getBundle().getBundleContext(), odp, mon);
// See if the client requested a specific compiler level
String compilerLevel = System.getenv(NSFODPConstants.PROP_COMPILERLEVEL);
if (StringUtil.isNotEmpty(compilerLevel)) {
compiler.setCompilerLevel(compilerLevel);
}
String appendTimestamp = System.getenv(NSFODPConstants.PROP_APPENDTIMESTAMPTOTITLE);
if ("true".equals(appendTimestamp)) {
// $NON-NLS-1$
compiler.setAppendTimestampToTitle(true);
}
String templateName = System.getenv(NSFODPConstants.PROP_TEMPLATENAME);
if (StringUtil.isNotEmpty(templateName)) {
compiler.setTemplateName(templateName);
String templateVersion = System.getenv(NSFODPConstants.PROP_TEMPLATEVERSION);
if (StringUtil.isNotEmpty(templateVersion)) {
compiler.setTemplateVersion(templateVersion);
}
}
String setXspOptions = System.getenv(NSFODPConstants.PROP_SETPRODUCTIONXSPOPTIONS);
if ("true".equals(setXspOptions)) {
// $NON-NLS-1$
compiler.setSetProductionXspOptions(true);
}
String odsRelease = System.getenv(NSFODPConstants.PROP_ODSRELEASE);
if (StringUtil.isNotEmpty(odsRelease)) {
compiler.setOdsRelease(odsRelease);
}
String compileBasicLs = System.getenv(NSFODPConstants.PROP_COMPILEBASICLS);
if ("true".equals(compileBasicLs)) {
// $NON-NLS-1$
compiler.setCompileBasicElementLotusScript(true);
}
if (updateSites != null && !updateSites.isEmpty()) {
updateSites.stream().map(FilesystemUpdateSite::new).forEach(compiler::addUpdateSite);
}
exec.submit(() -> {
try {
Path nsf = compiler.compile();
Files.move(nsf, outputFile, StandardCopyOption.REPLACE_EXISTING);
mon.done();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}).get();
// $NON-NLS-1$
System.out.println(getClass().getName() + "#end");
exec.shutdownNow();
exec.awaitTermination(30, TimeUnit.SECONDS);
return EXIT_OK;
} finally {
NotesThread.stermThread();
}
}
use of org.openntf.nsfodp.commons.odp.notesapi.NotesAPI in project org.openntf.nsfodp by OpenNTF.
the class ODPExporterServlet method handle.
protected void handle(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// $NON-NLS-1$
boolean post = "POST".equals(req.getMethod());
Principal user = req.getUserPrincipal();
resp.setBufferSize(0);
resp.setStatus(HttpServletResponse.SC_OK);
ServletOutputStream os = resp.getOutputStream();
Set<Path> cleanup = new HashSet<>();
try {
if (!ALLOW_ANONYMOUS && "Anonymous".equalsIgnoreCase(user.getName())) {
// $NON-NLS-1$
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
// $NON-NLS-1$
resp.setContentType("text/plain");
os.println(Messages.ODPExporterServlet_anonymousAccessDisallowed);
return;
}
try (NotesAPI session = NotesAPI.get()) {
NDatabase database;
if (post) {
// Then read the NSF from the body
String contentType = req.getContentType();
if (!"application/octet-stream".equals(contentType)) {
// $NON-NLS-1$
throw new IllegalArgumentException(MessageFormat.format(Messages.ODPExporterServlet_mismatchedContentType, NSFODPConstants.HEADER_DATABASE_PATH, contentType));
}
// $NON-NLS-1$
Path nsfFile = Files.createTempFile(NSFODPUtil.getTempDirectory(), getClass().getName(), ".nsf");
cleanup.add(nsfFile);
try (InputStream reqInputStream = req.getInputStream()) {
Files.copy(reqInputStream, nsfFile, StandardCopyOption.REPLACE_EXISTING);
}
database = session.openDatabase(nsfFile.toString());
} else {
// Then look for an NSF path in the headers
String databasePath = req.getHeader(NSFODPConstants.HEADER_DATABASE_PATH);
if (StringUtil.isEmpty(databasePath)) {
throw new IllegalArgumentException(MessageFormat.format(Messages.ODPExporterServlet_dbPathMissing, NSFODPConstants.HEADER_DATABASE_PATH));
}
// Verify that the user can indeed export this DB
try (NotesAPI userApi = NotesAPI.get(user.getName(), false, false)) {
try (NDatabase userDb = userApi.openDatabase(databasePath)) {
if (userDb.getCurrentAccessLevel() < 5) {
// Designer access
throw new UnsupportedOperationException(MessageFormat.format(Messages.ODPExporterServlet_insufficientAccess, user.getName(), databasePath));
}
}
}
database = session.openDatabase(databasePath);
}
try {
IProgressMonitor mon = new LineDelimitedJsonProgressMonitor(os);
ODPExporter exporter = new ODPExporter(database);
String binaryDxl = req.getHeader(NSFODPConstants.HEADER_BINARY_DXL);
if ("true".equals(binaryDxl)) {
// $NON-NLS-1$
exporter.setBinaryDxl(true);
}
String swiperFilter = req.getHeader(NSFODPConstants.HEADER_SWIPER_FILTER);
if ("true".equals(swiperFilter)) {
// $NON-NLS-1$
exporter.setSwiperFilter(true);
}
String richTextAsItemData = req.getHeader(NSFODPConstants.HEADER_RICH_TEXT_AS_ITEM_DATA);
if ("true".equals(richTextAsItemData)) {
// $NON-NLS-1$
exporter.setRichTextAsItemData(true);
}
exporter.setProjectName(req.getHeader(NSFODPConstants.HEADER_PROJECT_NAME));
exporter.setOdpType(ODPType.ZIP);
Path result = exporter.export();
cleanup.add(result);
mon.done();
Files.copy(result, os);
} finally {
if (post) {
String filePath = database.getFilePath();
database.close();
session.deleteDatabase(filePath);
}
}
}
} catch (Throwable e) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter out = new PrintWriter(baos);
e.printStackTrace(out);
out.flush();
os.println(LineDelimitedJsonProgressMonitor.message(// $NON-NLS-1$ //$NON-NLS-2$
"type", // $NON-NLS-1$ //$NON-NLS-2$
"error", // $NON-NLS-1$
"stackTrace", // $NON-NLS-1$
baos.toString()));
} finally {
NSFODPUtil.deltree(cleanup);
}
}
Aggregations