/* * Copyright (c) 2010-2015 Evolveum * * 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. */ package com.evolveum.midpoint.web.page.admin.configuration; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.MiscSchemaUtil; import com.evolveum.midpoint.security.api.AuthorizationConstants; import com.evolveum.midpoint.task.api.Task; 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.application.AuthorizationAction; import com.evolveum.midpoint.web.application.PageDescriptor; import com.evolveum.midpoint.web.component.AjaxButton; import com.evolveum.midpoint.web.component.AjaxSubmitButton; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.web.component.AceEditor; import com.evolveum.midpoint.web.page.admin.configuration.component.ImportOptionsPanel; import com.evolveum.midpoint.web.security.MidPointApplication; import com.evolveum.midpoint.web.security.WebApplicationConfiguration; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ImportOptionsType; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.ReaderInputStream; import org.apache.commons.lang.StringUtils; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.Radio; import org.apache.wicket.markup.html.form.RadioGroup; import org.apache.wicket.markup.html.form.upload.FileUpload; import org.apache.wicket.markup.html.form.upload.FileUploadField; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.util.file.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; /** * @author lazyman * @author mserbak */ @PageDescriptor(url = "/admin/config/import", action = { @AuthorizationAction(actionUri = PageAdminConfiguration.AUTH_CONFIGURATION_ALL, label = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_LABEL, description = PageAdminConfiguration.AUTH_CONFIGURATION_ALL_DESCRIPTION), @AuthorizationAction(actionUri = AuthorizationConstants.AUTZ_UI_CONFIGURATION_IMPORT_URL, label = "PageImportObject.auth.configImport.label", description = "PageImportObject.auth.configImport.description") }) public class PageImportObject extends PageAdminConfiguration { private static final Trace LOGGER = TraceManager.getTrace(PageImportObject.class); private static final String DOT_CLASS = PageImportObject.class.getName() + "."; private static final String OPERATION_IMPORT_FILE = DOT_CLASS + "importFile"; private static final String OPERATION_IMPORT_XML = DOT_CLASS + "importXml"; private static final String ID_MAIN_FORM = "mainForm"; private static final String ID_BUTTON_BAR = "buttonBar"; private static final String ID_IMPORT_OPTIONS = "importOptions"; private static final String ID_IMPORT_RADIO_GROUP = "importRadioGroup"; private static final String ID_FILE_RADIO = "fileRadio"; private static final String ID_XML_RADIO = "xmlRadio"; private static final String ID_BACK_BUTTON = "back"; private static final String ID_IMPORT_FILE_BUTTON = "importFileButton"; private static final String ID_IMPORT_XML_BUTTON = "importXmlButton"; private static final String ID_INPUT = "input"; private static final String ID_INPUT_ACE = "inputAce"; private static final String ID_ACE_EDITOR = "aceEditor"; private static final String ID_INPUT_FILE_LABEL = "inputFileLabel"; private static final String ID_INPUT_FILE = "inputFile"; private static final String ID_FILE_INPUT = "fileInput"; private static final Integer INPUT_FILE = 1; private static final Integer INPUT_XML = 2; private LoadableModel<ImportOptionsType> model; private IModel<String> xmlEditorModel; public PageImportObject() { model = new LoadableModel<ImportOptionsType>(false) { @Override protected ImportOptionsType load() { return MiscSchemaUtil.getDefaultImportOptions(); } }; xmlEditorModel = new Model<String>(null); initLayout(); } private void initLayout() { Form mainForm = new Form(ID_MAIN_FORM); add(mainForm); ImportOptionsPanel importOptions = new ImportOptionsPanel(ID_IMPORT_OPTIONS, model); mainForm.add(importOptions); final WebMarkupContainer input = new WebMarkupContainer(ID_INPUT); input.setOutputMarkupId(true); mainForm.add(input); final WebMarkupContainer buttonBar = new WebMarkupContainer(ID_BUTTON_BAR); buttonBar.setOutputMarkupId(true); mainForm.add(buttonBar); final IModel<Integer> groupModel = new Model<Integer>(INPUT_FILE); RadioGroup importRadioGroup = new RadioGroup(ID_IMPORT_RADIO_GROUP, groupModel); importRadioGroup.add(new AjaxFormChoiceComponentUpdatingBehavior() { @Override protected void onUpdate(AjaxRequestTarget target) { target.add(input); target.add(buttonBar); } }); mainForm.add(importRadioGroup); Radio fileRadio = new Radio(ID_FILE_RADIO, new Model(INPUT_FILE), importRadioGroup); importRadioGroup.add(fileRadio); Radio xmlRadio = new Radio(ID_XML_RADIO, new Model(INPUT_XML), importRadioGroup); importRadioGroup.add(xmlRadio); WebMarkupContainer inputAce = new WebMarkupContainer(ID_INPUT_ACE); addVisibileForInputType(inputAce, INPUT_XML, groupModel); input.add(inputAce); AceEditor aceEditor = new AceEditor(ID_ACE_EDITOR, xmlEditorModel); aceEditor.setOutputMarkupId(true); inputAce.add(aceEditor); WebMarkupContainer inputFileLabel = new WebMarkupContainer(ID_INPUT_FILE_LABEL); addVisibileForInputType(inputFileLabel, INPUT_FILE, groupModel); input.add(inputFileLabel); WebMarkupContainer inputFile = new WebMarkupContainer(ID_INPUT_FILE); addVisibileForInputType(inputFile, INPUT_FILE, groupModel); input.add(inputFile); FileUploadField fileInput = new FileUploadField(ID_FILE_INPUT); inputFile.add(fileInput); initButtons(buttonBar, groupModel); } private void addVisibileForInputType(Component comp, final Integer type, final IModel<Integer> groupModel) { comp.add(new VisibleEnableBehaviour() { @Override public boolean isVisible() { return type.equals(groupModel.getObject()); } }); } private void initButtons(WebMarkupContainer buttonBar, IModel<Integer> inputType) { AjaxButton backButton = new AjaxButton(ID_BACK_BUTTON, createStringResource("PageCertCampaign.button.back")) { @Override public void onClick(AjaxRequestTarget target) { redirectBack(); } }; backButton.add(new VisibleEnableBehaviour() { @Override public boolean isVisible() { return canRedirectBack(); } }); buttonBar.add(backButton); AjaxSubmitButton saveFileButton = new AjaxSubmitButton(ID_IMPORT_FILE_BUTTON, createStringResource("PageImportObject.button.import")) { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { savePerformed(false, OPERATION_IMPORT_FILE, target); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(getFeedbackPanel()); } }; addVisibileForInputType(saveFileButton, INPUT_FILE, inputType); buttonBar.add(saveFileButton); AjaxSubmitButton saveXmlButton = new AjaxSubmitButton(ID_IMPORT_XML_BUTTON, createStringResource("PageImportObject.button.import")) { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { savePerformed(true, OPERATION_IMPORT_XML, target); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { target.add(getFeedbackPanel()); } }; addVisibileForInputType(saveXmlButton, INPUT_XML, inputType); buttonBar.add(saveXmlButton); } private FileUpload getUploadedFile() { FileUploadField file = (FileUploadField) get( createComponentPath(ID_MAIN_FORM, ID_INPUT, ID_INPUT_FILE, ID_FILE_INPUT)); return file.getFileUpload(); } private boolean validateInput(boolean raw) { if (raw) { return StringUtils.isNotEmpty(xmlEditorModel.getObject()); } return getUploadedFile() != null; } private InputStream getInputStream(boolean raw) throws Exception { if (raw) { return IOUtils.toInputStream(xmlEditorModel.getObject(), "utf-8"); } File newFile = null; try { // Create new file MidPointApplication application = getMidpointApplication(); WebApplicationConfiguration config = application.getWebApplicationConfiguration(); File folder = new File(config.getImportFolder()); if (!folder.exists() || !folder.isDirectory()) { folder.mkdir(); } FileUpload uploadedFile = getUploadedFile(); newFile = new File(folder, uploadedFile.getClientFileName()); // Check new file, delete if it already exists if (newFile.exists()) { newFile.delete(); } // Save file newFile.createNewFile(); uploadedFile.writeTo(newFile); InputStreamReader reader = new InputStreamReader(new FileInputStream(newFile), "utf-8"); return new ReaderInputStream(reader, reader.getEncoding()); } finally { if (newFile != null) { FileUtils.deleteQuietly(newFile); } } } private void clearOldFeedback(){ getSession().getFeedbackMessages().clear(); getFeedbackMessages().clear(); } private void savePerformed(boolean raw, String operationName, AjaxRequestTarget target) { clearOldFeedback(); OperationResult result = new OperationResult(operationName); if (!validateInput(raw)) { error(getString("pageImportObject.message.nullFile")); target.add(getFeedbackPanel()); return; } InputStream stream = null; try { Task task = createSimpleTask(operationName); stream = getInputStream(raw); getModelService().importObjectsFromStream(stream, model.getObject(), task, result); result.recomputeStatus(); } catch (Exception ex) { result.recordFatalError("Couldn't import file.", ex); LoggingUtils.logUnexpectedException(LOGGER, "Couldn't import file", ex); } finally { if (stream != null) { IOUtils.closeQuietly(stream); } } showResult(result); target.add(PageImportObject.this); } }