package com.evolveum.midpoint.web.page.admin.configuration.component; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebComponentUtil; import com.evolveum.midpoint.model.api.ModelService; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.query.ObjectQuery; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.ResultHandler; import com.evolveum.midpoint.schema.SchemaConstantsGenerated; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.constants.SchemaConstants; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.LoggingUtils; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.AjaxDownloadBehaviorFromFile; import com.evolveum.midpoint.web.page.error.PageError; import com.evolveum.midpoint.web.security.MidPointApplication; import com.evolveum.midpoint.web.security.WebApplicationConfiguration; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.wicket.RestartResponseException; import org.apache.wicket.util.file.File; import org.apache.wicket.util.file.Files; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; /** * @author lazyman */ public class PageDebugDownloadBehaviour extends AjaxDownloadBehaviorFromFile { private static final Trace LOGGER = TraceManager.getTrace(PageDebugDownloadBehaviour.class); private static final String DOT_CLASS = PageDebugDownloadBehaviour.class.getName() + "."; private static final String OPERATION_SEARCH_OBJECT = DOT_CLASS + "loadObjects"; private static final String OPERATION_CREATE_DOWNLOAD_FILE = DOT_CLASS + "createDownloadFile"; private boolean exportAll; private Class<? extends ObjectType> type; private boolean useZip; private ObjectQuery query; public boolean isExportAll() { return exportAll; } public void setExportAll(boolean exportAll) { this.exportAll = exportAll; } public Class<? extends ObjectType> getType() { if (type == null) { return ObjectType.class; } return type; } public void setType(Class<? extends ObjectType> type) { this.type = type; } public ObjectQuery getQuery() { return query; } public void setQuery(ObjectQuery query) { this.query = query; } public boolean isUseZip() { return useZip; } public void setUseZip(boolean useZip) { this.useZip = useZip; } @Override protected File initFile() { PageBase page = getPage(); OperationResult result = new OperationResult(OPERATION_CREATE_DOWNLOAD_FILE); MidPointApplication application = page.getMidpointApplication(); WebApplicationConfiguration config = application.getWebApplicationConfiguration(); File folder = new File(config.getExportFolder()); if (!folder.exists() || !folder.isDirectory()) { folder.mkdir(); } String suffix = isUseZip() ? "zip" : "xml"; String fileName = "ExportedData_" + getType().getSimpleName() + "_" + System.currentTimeMillis() + "." + suffix; File file = new File(folder, fileName); Writer writer = null; try { LOGGER.debug("Creating file '{}'.", new Object[]{file.getAbsolutePath()}); writer = createWriter(file); LOGGER.debug("Exporting objects."); dumpHeader(writer); dumpObjectsToStream(writer, result); dumpFooter(writer); LOGGER.debug("Export finished."); result.recomputeStatus(); } catch (Exception ex) { LoggingUtils.logUnexpectedException(LOGGER, "Couldn't init download link", ex); result.recordFatalError("Couldn't init download link", ex); } finally { if (writer != null) { IOUtils.closeQuietly(writer); } } if (!WebComponentUtil.isSuccessOrHandledError(result)) { page.showResult(result); page.getSession().error(page.getString("pageDebugList.message.createFileException")); LOGGER.debug("Removing file '{}'.", new Object[]{file.getAbsolutePath()}); Files.remove(file); throw new RestartResponseException(PageError.class); } return file; } private Writer createWriter(File file) throws IOException { OutputStream stream; if (isUseZip()) { ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file)); String fileName = file.getName(); if (StringUtils.isNotEmpty(file.getExtension())) { fileName = fileName.replaceAll(file.getExtension() + "$", "xml"); } ZipEntry entry = new ZipEntry(fileName); out.putNextEntry(entry); stream = out; } else { stream = new FileOutputStream(file); } return new OutputStreamWriter(stream); } private <T extends ObjectType> void dumpObjectsToStream(final Writer writer, OperationResult result) throws Exception { final PageBase page = getPage(); ResultHandler handler = new ResultHandler() { @Override public boolean handle(PrismObject object, OperationResult parentResult) { try { String xml = page.getPrismContext().serializeObjectToString(object, PrismContext.LANG_XML); writer.write('\t'); writer.write(xml); writer.write('\n'); } catch (IOException ex) { throw new SystemException(ex.getMessage(), ex); } catch (SchemaException ex) { throw new SystemException(ex.getMessage(), ex); } return true; } }; ModelService service = page.getModelService(); GetOperationOptions options = GetOperationOptions.createRaw(); options.setResolveNames(true); service.searchObjectsIterative(type, query, handler, SelectorOptions.createCollection(options), page.createSimpleTask(OPERATION_SEARCH_OBJECT), result); } private PageBase getPage() { return (PageBase) getComponent().getPage(); } private void dumpFooter(Writer writer) throws IOException { writer.write("</objects>"); } private void dumpHeader(Writer writer) throws IOException { writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); writer.write("<objects xmlns=\""); writer.write(SchemaConstantsGenerated.NS_COMMON); writer.write("\"\n"); writer.write("\txmlns:c=\""); writer.write(SchemaConstantsGenerated.NS_COMMON); writer.write("\"\n"); writer.write("\txmlns:org=\""); writer.write(SchemaConstants.NS_ORG); writer.write("\">\n"); } }