/** * Encapsulates the logic of registering import handlers, generating the manifest, and performing * the export */ public ZipExportProcessor(String path, IUnifiedRepository repository, boolean withManifest) { this.withManifest = withManifest; // set a default path at root if missing if (StringUtils.isEmpty(path)) { this.path = "/"; } else { this.path = path; } this.unifiedRepository = repository; this.exportHandlerList = new ArrayList<ExportHandler>(); this.exportManifest = new ExportManifest(); // set created by and create date in manifest information IPentahoSession session = PentahoSessionHolder.getSession(); Date todaysDate = new Date(); SimpleDateFormat dateFormat = new SimpleDateFormat(EXPORT_INFO_DATE_FORMAT); SimpleDateFormat timeFormat = new SimpleDateFormat(EXPORT_INFO_TIME_FORMAT); exportManifest.getManifestInformation().setExportBy(session.getName()); exportManifest .getManifestInformation() .setExportDate(dateFormat.format(todaysDate) + " " + timeFormat.format(todaysDate)); }
private void initializeAclManifest(IRepositoryFileBundle file) { try { byte[] bytes = IOUtils.toByteArray(file.getInputStream()); ByteArrayInputStream in = new ByteArrayInputStream(bytes); getImportSession().setManifest(ExportManifest.fromXml(in)); } catch (Exception e) { log.trace(e); } }
/** * create an entry in the export manifest for this file or folder * * @param repositoryFile * @throws ExportException */ private void addToManifest(RepositoryFile repositoryFile) throws ExportException { if (this.withManifest) { // add this entity to the manifest RepositoryFileAcl fileAcl = unifiedRepository.getAcl(repositoryFile.getId()); try { exportManifest.add(repositoryFile, fileAcl); } catch (ExportManifestFormatException e) { throw new ExportException(e.getMessage()); } } }
protected void importMetaStore(ExportManifest manifest, boolean overwrite) { // get the metastore if (manifest != null) { ExportManifestMetaStore manifestMetaStore = manifest.getMetaStore(); if (manifestMetaStore != null) { // get the zipped metastore from the export bundle RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder() .path(manifestMetaStore.getFile()) .name(manifestMetaStore.getName()) .withParam("description", manifestMetaStore.getDescription()) .charSet("UTF-8") .overwriteFile(overwrite) .mime("application/vnd.pentaho.metastore"); cachedImports.put(manifestMetaStore.getFile(), bundleBuilder); } } }
public void importFile(IPlatformImportBundle bundle) throws PlatformImportException, DomainIdNullException, DomainAlreadyExistsException, DomainStorageException, IOException { RepositoryFileImportBundle importBundle = (RepositoryFileImportBundle) bundle; ZipInputStream zipImportStream = new ZipInputStream(bundle.getInputStream()); SolutionRepositoryImportSource importSource = new SolutionRepositoryImportSource(zipImportStream); LocaleFilesProcessor localeFilesProcessor = new LocaleFilesProcessor(); setOverwriteFile(bundle.overwriteInRepository()); // importSession.set(ImportSession.getSession()); IPlatformImporter importer = PentahoSystem.get(IPlatformImporter.class); cachedImports = new HashMap<String, RepositoryFileImportBundle.Builder>(); // Process Manifest Settings ExportManifest manifest = getImportSession().getManifest(); String manifestVersion = null; if (manifest != null) { manifestVersion = manifest.getManifestInformation().getManifestVersion(); } // Process Metadata if (manifest != null) { // import the users Map<String, List<String>> roleToUserMap = importUsers(manifest.getUserExports()); // import the roles importRoles(manifest.getRoleExports(), roleToUserMap); List<ExportManifestMetadata> metadataList = manifest.getMetadataList(); for (ExportManifestMetadata exportManifestMetadata : metadataList) { String domainId = exportManifestMetadata.getDomainId(); boolean overWriteInRepository = isOverwriteFile(); RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder() .charSet("UTF-8") .hidden(false) // let the parent bundle control whether or not to preserve DSW settings .preserveDsw(bundle.isPreserveDsw()) .overwriteFile(overWriteInRepository) .mime("text/xmi+xml") .withParam("domain-id", domainId); cachedImports.put(exportManifestMetadata.getFile(), bundleBuilder); } // Process Mondrian List<ExportManifestMondrian> mondrianList = manifest.getMondrianList(); for (ExportManifestMondrian exportManifestMondrian : mondrianList) { String catName = exportManifestMondrian.getCatalogName(); Parameters parametersMap = exportManifestMondrian.getParameters(); StringBuilder parametersStr = new StringBuilder(); for (String s : parametersMap.keySet()) { parametersStr.append(s).append("=").append(parametersMap.get(s)).append(sep); } RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder() .charSet("UTF_8") .hidden(false) .name(catName) .overwriteFile(isOverwriteFile()) .mime("application/vnd.pentaho.mondrian+xml") .withParam("parameters", parametersStr.toString()) .withParam("domain-id", catName); // TODO: this is // definitely // named wrong // at the very // least. // pass as param if not in parameters string String xmlaEnabled = "" + exportManifestMondrian.isXmlaEnabled(); bundleBuilder.withParam("EnableXmla", xmlaEnabled); cachedImports.put(exportManifestMondrian.getFile(), bundleBuilder); String annotationsFile = exportManifestMondrian.getAnnotationsFile(); if (annotationsFile != null) { RepositoryFileImportBundle.Builder annotationsBundle = new RepositoryFileImportBundle.Builder() .path( MondrianCatalogRepositoryHelper.ETC_MONDRIAN_JCR_FOLDER + RepositoryFile.SEPARATOR + catName) .name("annotations.xml") .charSet("UTF_8") .overwriteFile(isOverwriteFile()) .mime("text/xml") .hidden(false) .withParam("domain-id", catName); cachedImports.put(annotationsFile, annotationsBundle); } } } importMetaStore(manifest, bundle.overwriteInRepository()); for (IRepositoryFileBundle file : importSource.getFiles()) { String fileName = file.getFile().getName(); String actualFilePath = file.getPath(); if (manifestVersion != null) { fileName = ExportFileNameEncoder.decodeZipFileName(fileName); actualFilePath = ExportFileNameEncoder.decodeZipFileName(actualFilePath); } String repositoryFilePath = RepositoryFilenameUtils.concat( PentahoPlatformImporter.computeBundlePath(actualFilePath), fileName); if (this.cachedImports.containsKey(repositoryFilePath)) { byte[] bytes = IOUtils.toByteArray(file.getInputStream()); RepositoryFileImportBundle.Builder builder = cachedImports.get(repositoryFilePath); builder.input(new ByteArrayInputStream(bytes)); importer.importFile(build(builder)); continue; } RepositoryFileImportBundle.Builder bundleBuilder = new RepositoryFileImportBundle.Builder(); InputStream bundleInputStream = null; String decodedFilePath = file.getPath(); RepositoryFile decodedFile = file.getFile(); if (manifestVersion != null) { decodedFile = new RepositoryFile.Builder(decodedFile) .path(decodedFilePath) .name(fileName) .title(fileName) .build(); decodedFilePath = ExportFileNameEncoder.decodeZipFileName(file.getPath()); } if (file.getFile().isFolder()) { bundleBuilder.mime("text/directory"); bundleBuilder.file(decodedFile); fileName = repositoryFilePath; repositoryFilePath = importBundle.getPath(); } else { byte[] bytes = IOUtils.toByteArray(file.getInputStream()); bundleInputStream = new ByteArrayInputStream(bytes); // If is locale file store it for later processing. if (localeFilesProcessor.isLocaleFile(file, importBundle.getPath(), bytes)) { log.trace("Skipping [" + repositoryFilePath + "], it is a locale property file"); continue; } bundleBuilder.input(bundleInputStream); bundleBuilder.mime(solutionHelper.getMime(fileName)); String filePath = (decodedFilePath.equals("/") || decodedFilePath.equals("\\")) ? "" : decodedFilePath; repositoryFilePath = RepositoryFilenameUtils.concat(importBundle.getPath(), filePath); } bundleBuilder.name(fileName); bundleBuilder.path(repositoryFilePath); String sourcePath; if (decodedFilePath.startsWith("/")) { sourcePath = RepositoryFilenameUtils.concat(decodedFilePath.substring(1), fileName); } else { if (file.getFile().isFolder()) { sourcePath = fileName; } else { sourcePath = RepositoryFilenameUtils.concat(decodedFilePath, fileName); } } // This clause was added for processing ivb files so that it would not try process acls on // folders that the user // may not have rights to such as /home or /public if (manifest != null && manifest.getExportManifestEntity(sourcePath) == null && file.getFile().isFolder()) { continue; } getImportSession().setCurrentManifestKey(sourcePath); bundleBuilder.charSet(bundle.getCharset()); bundleBuilder.overwriteFile(bundle.overwriteInRepository()); bundleBuilder.hidden(isFileHidden(bundle, sourcePath)); bundleBuilder.applyAclSettings(bundle.isApplyAclSettings()); bundleBuilder.retainOwnership(bundle.isRetainOwnership()); bundleBuilder.overwriteAclSettings(bundle.isOverwriteAclSettings()); bundleBuilder.acl(getImportSession().processAclForFile(sourcePath)); IPlatformImportBundle platformImportBundle = build(bundleBuilder); importer.importFile(platformImportBundle); if (bundleInputStream != null) { bundleInputStream.close(); bundleInputStream = null; } } if (manifest != null) { List<JobScheduleRequest> scheduleList = manifest.getScheduleList(); if (scheduleList != null) { SchedulerResource schedulerResource = new SchedulerResource(); for (JobScheduleRequest jobScheduleRequest : scheduleList) { try { Response response = createSchedulerJob(schedulerResource, jobScheduleRequest); if (response.getStatus() == Response.Status.OK.getStatusCode()) { if (response.getEntity() != null) { // get the schedule job id from the response and add it to the import session ImportSession.getSession() .addImportedScheduleJobId(response.getEntity().toString()); } } } catch (Exception e) { // there is a scenario where if the file scheduled has a space in the path, that it // won't work. the di server // replaces spaces with underscores and the export mechanism can't determine if it needs // this to happen or not // so, if we failed to import and there is a space in the path, try again but this time // with replacing the space(s) if (jobScheduleRequest.getInputFile().contains(" ") || jobScheduleRequest.getOutputFile().contains(" ")) { log.info( "Could not import schedule, attempting to replace spaces with underscores and retrying: " + jobScheduleRequest.getInputFile()); jobScheduleRequest.setInputFile( jobScheduleRequest.getInputFile().replaceAll(" ", "_")); jobScheduleRequest.setOutputFile( jobScheduleRequest.getOutputFile().replaceAll(" ", "_")); try { Response response = createSchedulerJob(schedulerResource, jobScheduleRequest); if (response.getStatus() == Response.Status.OK.getStatusCode()) { if (response.getEntity() != null) { // get the schedule job id from the response and add it to the import session ImportSession.getSession() .addImportedScheduleJobId(response.getEntity().toString()); } } } catch (Exception ex) { throw new PlatformImportException( Messages.getInstance() .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage())); } } else { throw new PlatformImportException( Messages.getInstance() .getString( "SolutionImportHandler.ERROR_0001_ERROR_CREATING_SCHEDULE", e.getMessage())); } } } } // Add Pentaho Connections List<org.pentaho.database.model.DatabaseConnection> datasourceList = manifest.getDatasourceList(); if (datasourceList != null) { IDatasourceMgmtService datasourceMgmtSvc = PentahoSystem.get(IDatasourceMgmtService.class); for (org.pentaho.database.model.DatabaseConnection databaseConnection : datasourceList) { if (databaseConnection.getDatabaseType() == null) { // don't try to import the connection if there is no type it will cause an error // However, if this is the DI Server, and the connection is defined in a ktr, it will // import automatically log.warn( "Can't import connection " + databaseConnection.getName() + " because it doesn't have a databaseType"); continue; } try { IDatabaseConnection existingDBConnection = datasourceMgmtSvc.getDatasourceByName(databaseConnection.getName()); if (existingDBConnection != null && existingDBConnection.getName() != null) { if (isOverwriteFile()) { databaseConnection.setId(existingDBConnection.getId()); datasourceMgmtSvc.updateDatasourceByName( databaseConnection.getName(), databaseConnection); } } else { datasourceMgmtSvc.createDatasource(databaseConnection); } } catch (Exception e) { e.printStackTrace(); } } } } // Process locale files. localeFilesProcessor.processLocaleFiles(importer); }
/** * Performs the export process, returns a zip File object * * @throws ExportException indicates an error in import processing */ public File performExport(RepositoryFile exportRepositoryFile) throws ExportException, IOException { File exportFile = null; // create temp file exportFile = File.createTempFile(EXPORT_TEMP_FILENAME_PREFIX, EXPORT_TEMP_FILENAME_EXT); exportFile.deleteOnExit(); // get the file path String filePath = new File(this.path).getParent(); if (filePath == null) { filePath = "/"; } // send a response right away if not found if (exportRepositoryFile == null) { // todo: add to messages.properties throw new FileNotFoundException("JCR file not found: " + this.path); } ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(exportFile)); if (exportRepositoryFile.isFolder()) { // Handle recursive export exportManifest .getManifestInformation() .setRootFolder(path.substring(0, path.lastIndexOf("/") + 1)); // don't zip root folder without name if (!ClientRepositoryPaths.getRootFolderPath().equals(exportRepositoryFile.getPath())) { zos.putNextEntry(new ZipEntry(getZipEntryName(exportRepositoryFile, filePath))); } exportDirectory(exportRepositoryFile, zos, filePath); } else { exportManifest .getManifestInformation() .setRootFolder(path.substring(0, path.lastIndexOf("/") + 1)); exportFile(exportRepositoryFile, zos, filePath); } if (this.withManifest) { // write manifest to zip output stream ZipEntry entry = new ZipEntry(EXPORT_MANIFEST_FILENAME); zos.putNextEntry(entry); // pass output stream to manifest class for writing try { exportManifest.toXml(zos); } catch (Exception e) { // todo: add to messages.properties log.error("Error generating export XML"); } zos.closeEntry(); } zos.close(); // clean up exportManifest = null; zos = null; return exportFile; }