From ef0f16d99c714496c881a2fad5ce1b3125365fd7 Mon Sep 17 00:00:00 2001 From: jensp Date: Tue, 18 Apr 2017 10:57:10 +0000 Subject: [PATCH] CCM NG/ccm-cms: - Ported FormUploadSection to NG - BinaryAssetForm as base for all other assets which extend BinaryAsset CCM NG/ccm-core: - First part of a JPQL console for testing JPQL queries git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4679 8810af33-2d31-482b-a856-94f89814c4df --- .../src/main/webapp/WEB-INF/web.xml | 5 + .../arsdigita/cms/ui/FileUploadSection.java | 474 ++++++++++++++++++ .../arsdigita/cms/ui/assets/AssetForm.java | 8 +- .../cms/ui/assets/forms/BinaryAssetForm.java | 216 ++++++++ .../cms/ui/assets/forms/BookmarkForm.java | 13 +- .../assets/forms/ExternalVideoAssetForm.java | 14 +- .../ui/assets/forms/LegalMetadataForm.java | 25 +- .../cms/ui/assets/forms/SideNoteForm.java | 14 +- .../com/arsdigita/ui/admin/AdminServlet.java | 7 + .../com/arsdigita/ui/admin/JpqlConsole.java | 168 +++++++ .../ui/admin/AdminResources.properties | 3 + .../ui/admin/AdminResources_de.properties | 3 + .../ui/admin/AdminResources_en.properties | 3 + .../ui/admin/AdminResources_fr.properties | 3 + 14 files changed, 931 insertions(+), 25 deletions(-) create mode 100755 ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BinaryAssetForm.java create mode 100644 ccm-core/src/main/java/com/arsdigita/ui/admin/JpqlConsole.java diff --git a/ccm-bundle-devel-wildfly-web/src/main/webapp/WEB-INF/web.xml b/ccm-bundle-devel-wildfly-web/src/main/webapp/WEB-INF/web.xml index e60520629..94acbcd30 100644 --- a/ccm-bundle-devel-wildfly-web/src/main/webapp/WEB-INF/web.xml +++ b/ccm-bundle-devel-wildfly-web/src/main/webapp/WEB-INF/web.xml @@ -6,6 +6,11 @@ version="3.0"> LibreCCM Devel Bundle for Wildfly + + + ccm.develmode + true + diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java new file mode 100755 index 000000000..ce5263909 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/FileUploadSection.java @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +package com.arsdigita.cms.ui; + +import com.arsdigita.bebop.ColumnPanel; +import com.arsdigita.bebop.Container; +import com.arsdigita.bebop.FormData; +import com.arsdigita.bebop.FormSection; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.form.FileUpload; +import com.arsdigita.bebop.form.Option; +import com.arsdigita.bebop.form.OptionGroup; +import com.arsdigita.bebop.form.SingleSelect; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.dispatcher.MultipartHttpServletRequest; +import java.io.File; +import javax.activation.MimeType; +import javax.activation.MimeTypeParseException; +import javax.activation.MimetypesFileTypeMap; +import org.librecms.CmsConstants; + +/** + * A form section with two widgets: a mime-type selection widget and a file + * upload widget. The section will attempt to automatically guess the mime type + * from the filename (if necessary), and return the mime type. + * + * @author Stanislav Freidin (sfreidin@arsdigita.com) + * @author Jens Pelzetter + */ +public class FileUploadSection extends FormSection { + + private SingleSelect mimeWidget; + private FileUpload fileWidget; + private String mimePrefix; + private String defaultMimeType; + private String parameterPrefix; + + /** + * The mime type widget + */ + public static final String MIME_TYPE = "mime_type"; + + /** + * The file upload widget + */ + public static final String FILE_UPLOAD = "file_upload"; + + /** + * Automatically guess the mime type + */ + public static final String GUESS_MIME = "-guess-"; + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @param panel The panel that is to be used to lay out the components + * + */ + public FileUploadSection(final GlobalizedMessage mimeLabel, + final String mimePrefix, + final String defaultMimeType, + final Container panel) { + this(mimeLabel, mimePrefix, defaultMimeType, "", panel); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @param panel The panel that is to be used to lay out the components + * + * @deprecated use the same constructor but with the GlobalizedMessage for + * the mimeLabel + */ + public FileUploadSection(final String mimeLabel, + final String mimePrefix, + final String defaultMimeType, + final Container panel) { + // This takes advantage of the fact that the "key" is returned + // when it is not present in the message bundle + this(new GlobalizedMessage(mimeLabel), + mimePrefix, + defaultMimeType, + panel); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for + * parameter names so that more than 1 file upload widgets may be used per + * form + * + * @param panel The panel that is to be used to lay out the components + * + * @deprecated use the same constructor but with the GlobalizedMessage for + * the mimeLabel + */ + public FileUploadSection(final String mimeLabel, + final String mimePrefix, + final String defaultMimeType, + final String parameterPrefix, + final Container panel + ) { + // This takes advantage of the fact that the "key" is returned + // when it is not present in the message bundle + this(new GlobalizedMessage(mimeLabel, CmsConstants.CMS_BUNDLE), + mimePrefix, + defaultMimeType, + parameterPrefix, + panel); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for + * parameter names so that more than 1 file upload widgets may be used per + * form + * + * @param panel The panel that is to be used to lay out the components + * + */ + public FileUploadSection(final GlobalizedMessage mimeLabel, + final String mimePrefix, + final String defaultMimeType, + final String parameterPrefix, + final Container panel) { + + super(panel); + + this.mimePrefix = mimePrefix; + this.defaultMimeType = defaultMimeType; + if (parameterPrefix == null) { + this.parameterPrefix = ""; + } else { + this.parameterPrefix = parameterPrefix; + } + + add(new Label(mimeLabel, false)); + mimeWidget = new SingleSelect(getMimeTypeWidgetName()); + addMimeOptions(mimeWidget, mimePrefix); + mimeWidget + .addOption(new Option(GUESS_MIME, + new Label(new GlobalizedMessage( + "cms.ui.authoring.file_upload.auto_detect", + CmsConstants.CMS_BUNDLE)))); + + mimeWidget.setDefaultValue(GUESS_MIME); + add(mimeWidget); + + add(new Label(new GlobalizedMessage("cms.ui.upload_new_content", + CmsConstants.CMS_BUNDLE))); + fileWidget = new FileUpload(getFileUploadWidgetName()); + add(fileWidget); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for + * parameter names so that more than 1 file upload widgets may be used per + * form + * + */ + public FileUploadSection(final GlobalizedMessage mimeLabel, + final String mimePrefix, + final String defaultMimeType, + final String parameterPrefix) { + this(mimeLabel, + mimePrefix, + defaultMimeType, + parameterPrefix, + new ColumnPanel(2, true)); + final ColumnPanel panel = (ColumnPanel) getPanel(); + panel.setBorder(false); + panel.setPadColor("#FFFFFF"); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @param parameterPrefix Prepended to MIME_TYPE and FILE_UPLOAD for + * parameter names so that more than 1 file upload widgets may be used per + * form + * + * @deprecated use the same constructor but with the GlobalizedMessage for + * the mimeLabel + */ + public FileUploadSection(final String mimeLabel, + final String mimePrefix, + final String defaultMimeType, + final String parameterPrefix) { + // This takes advantage of the fact that the "key" is returned + // when it is not present in the message bundle + this(new GlobalizedMessage(mimeLabel, CmsConstants.CMS_BUNDLE), + mimePrefix, + defaultMimeType, + parameterPrefix); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The label for the mime type widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + * @deprecated use the same constructor but with the GlobalizedMessage for + * the mimeLabel + */ + public FileUploadSection(final String mimeLabel, + final String mimePrefix, + final String defaultMimeType) { + + // This takes advantage of the fact that the "key" is returned + // when it is not present in the message bundle + this(new GlobalizedMessage(mimeLabel, CmsConstants.CMS_BUNDLE), + mimePrefix, + defaultMimeType, + ""); + } + + /** + * Construct a new FileUploadSection + * + * @param mimeLabel The GlobalizedMessage for the label for the mime type + * widget + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + * @param defaultMimeType The default mime type that should be assumed if + * the guessing fails + * + */ + public FileUploadSection(GlobalizedMessage mimeLabel, + String mimePrefix, + String defaultMimeType) { + this(mimeLabel, mimePrefix, defaultMimeType, ""); + } + + /** + * Try to guess the mime type from the filename, and return it. The parent + * form should call this method in its process listener. Note that this + * method may return null if the mime type could not be guessed. + * + * @param event The form section event + * @return The mime type of the file. + */ + public MimeType getMimeType(final FormSectionEvent event) { + + final FormData data = event.getFormData(); + + final String fileName = (String) data.get(getFileUploadWidgetName()); + final String mimeTypeName = (String) data.get(getMimeTypeWidgetName()); + + // Guess the mime type from the filename + MimeType mimeType = null; + if (fileName != null) { + try { + if (GUESS_MIME.equals(mimeTypeName)) { + // Guess the mime type from the file extension + mimeType = new MimeType(MimetypesFileTypeMap + .getDefaultFileTypeMap() + .getContentType(fileName)); + } else { + mimeType = new MimeType(mimeTypeName); + } + } catch (MimeTypeParseException ex) { + mimeType = null; + } + } + + // Failed to guess it, failed to load it, fall back on the default + if (mimeType == null) { + try { + mimeType = new MimeType(defaultMimeType); + } catch (MimeTypeParseException ex) { + mimeType = null; + } + } + + return mimeType; + } + + /** + * Obtain a File object from the file upload widget. The containing form + * should call this method in its process listener. + * + * @param event The form section event + * @return + */ + public File getFile(final FormSectionEvent event) { + + final String fileName = getFileName(event); + + if (fileName != null && fileName.length() > 0) { + return ((MultipartHttpServletRequest) event + .getPageState() + .getRequest()) + .getFile(getFileUploadWidgetName()); + } + + return null; + } + + /** + * Obtain a filename from the file upload widget. The containing form should + * call this method in its process listener. + * + * @param event The form section event + * @return + */ + public String getFileName(final FormSectionEvent event) { + + return event + .getFormData() + .getString(getFileUploadWidgetName()); + } + + /** + * Set the value for the mime type widget. The containing form should call + * this method in its init listener + * + * @param event The form section event + * @param mimeType The mime type to set, such as "text/html" or "img/jpeg" + * + */ + public void setMimeType(final FormSectionEvent event, + final String mimeType) { + event + .getFormData() + .put(getMimeTypeWidgetName(), mimeType); + } + + /** + * @return the mime type widget + */ + public SingleSelect getMimeTypeWidget() { + return mimeWidget; + } + + /** + * @return the file upload widget + */ + public FileUpload getFileUploadWidget() { + return fileWidget; + } + + /** + * @return the parameter name prefix + */ + public String getParameterPrefix() { + return parameterPrefix; + } + + /** + * @return the file upload parameter name + */ + public String getFileUploadWidgetName() { + return parameterPrefix + FILE_UPLOAD; + } + + /** + * @return the mime typeparameter name + */ + public String getMimeTypeWidgetName() { + return parameterPrefix + MIME_TYPE; + } + + /** + * Add mime-type options to the option group by loading all mime types which + * match a certain prefix from the database + * + * @param mimeTypeOptions The mime type widget to which options should be added + * + * @param mimePrefix Populate the mime type widget with all mime types that + * match the prefix. Some of the possible prefixes are "text", "image", + * "binary", etc. + * + */ + public static void addMimeOptions(final OptionGroup mimeTypeOptions, + final String mimePrefix) { + +// MimeTypeCollection types; +// if (mimePrefix == null || mimePrefix.equals("")) { +// types = MimeType.getAllMimeTypes(); +// } else { +// types = MimeType.searchMimeTypes(mimePrefix + "/"); +// } +// while (types.next()) { +// MimeType type = types.getMimeType(); +// mimeTypeOptions.addOption(new Option(type.getMimeType(), type.getLabel())); +// } + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java index 1d6389925..3f4577c88 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetForm.java @@ -353,9 +353,9 @@ public abstract class AssetForm extends Form implements FormInitListener, final Asset asset; if (selectedAsset.isPresent()) { asset = selectedAsset.get(); - updateAsset(asset, state); + updateAsset(asset, event); } else { - asset = createAsset(state); + asset = createAsset(event); } asset.getTitle().addValue(getSelectedLocale(state), @@ -388,11 +388,11 @@ public abstract class AssetForm extends Form implements FormInitListener, protected abstract void showLocale(final PageState state); - protected abstract Asset createAsset(final PageState state) + protected abstract Asset createAsset(final FormSectionEvent event) throws FormProcessException; protected abstract void updateAsset(final Asset asset, - final PageState state) + final FormSectionEvent event) throws FormProcessException; @Override diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BinaryAssetForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BinaryAssetForm.java new file mode 100644 index 000000000..e28a1dea0 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BinaryAssetForm.java @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.cms.ui.assets.forms; + +import com.arsdigita.bebop.BoxPanel; +import com.arsdigita.bebop.FormProcessException; +import com.arsdigita.bebop.FormSection; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Text; +import com.arsdigita.bebop.event.FormSectionEvent; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.cms.ui.FileUploadSection; +import com.arsdigita.cms.ui.assets.AssetForm; +import com.arsdigita.cms.ui.assets.AssetPane; +import com.arsdigita.globalization.GlobalizedMessage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Objects; +import java.util.Optional; +import javax.activation.MimeType; +import org.librecms.CmsConstants; +import org.librecms.assets.BinaryAsset; +import org.librecms.contentsection.Asset; + +/** + * Base form for assets which extend {@link BinaryAsset}. + * + * @author Jens Pelzetter + */ +public abstract class BinaryAssetForm extends AssetForm { + + private TextArea description; + private Text fileName; + private Text mimeType; + private Text size; + private FileUploadSection fileUpload; + + public BinaryAssetForm(final AssetPane assetPane) { + super(assetPane); + } + + @Override + protected void addWidgets() { + + final BoxPanel panel = new BoxPanel(BoxPanel.VERTICAL); + + panel.add(new Label(new GlobalizedMessage( + "cms.ui.assets.binaryasset.description", + CmsConstants.CMS_BUNDLE))); + description = new TextArea("binaryasset-description"); + panel.add(description); + + panel.add(new Label( + new GlobalizedMessage("cms.ui.assets.binaryasset.filename", + CmsConstants.CMS_BUNDLE))); + fileName = new Text(); + panel.add(fileName); + + panel.add(new Label( + new GlobalizedMessage("cms.ui.assets.binaryasset.mimetype", + CmsConstants.CMS_BUNDLE))); + mimeType = new Text(); + panel.add(mimeType); + + panel.add(new Label( + new GlobalizedMessage("cms.ui.assets.binaryasset.size", + CmsConstants.CMS_BUNDLE))); + size = new Text(); + panel.add(size); + + fileUpload = new FileUploadSection( + new GlobalizedMessage("cms.ui.assets.binaryasset.mimetype", + CmsConstants.CMS_BUNDLE), + "", + ""); + + add(panel); + } + + @Override + protected void initForm(final PageState state, + final Optional selectedAsset) { + + if (selectedAsset.isPresent()) { + + if (!(selectedAsset.get() instanceof BinaryAsset)) { + throw new IllegalArgumentException(String.format( + "The provided asset must be an instanceof of class '%s' or " + + "an subclass but is na instanceof class '%s'.", + BinaryAsset.class.getName(), + selectedAsset.get().getClass().getName())); + } + + final BinaryAsset binaryAsset = (BinaryAsset) selectedAsset.get(); + + description.setValue(state, + binaryAsset + .getDescription() + .getValue(getSelectedLocale(state))); + + fileName.setText(binaryAsset.getFileName()); + mimeType.setText(binaryAsset.getMimeType().toString()); + size.setText(Long.toString(binaryAsset.getSize())); + } + + } + + @Override + protected void showLocale(final PageState state) { + + final Optional selectedAsset = getSelectedAsset(state); + + if (selectedAsset.isPresent()) { + if (!(getSelectedAsset(state).get() instanceof BinaryAsset)) { + throw new IllegalArgumentException( + "Selected asset is not a binary asset."); + } + + final BinaryAsset binaryAsset = (BinaryAsset) selectedAsset.get(); + + description.setValue(state, + binaryAsset + .getDescription() + .getValue(getSelectedLocale(state))); + } + + } + + @Override + protected Asset createAsset(final FormSectionEvent event) + throws FormProcessException { + + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); + + final BinaryAsset binaryAsset = createBinaryAsset(state); + + binaryAsset + .getDescription() + .addValue(getSelectedLocale(state), + (String) description.getValue(state)); + + setFileData(event, binaryAsset); + + return binaryAsset; + } + + protected abstract BinaryAsset createBinaryAsset(final PageState state); + + @Override + protected void updateAsset(final Asset asset, + final FormSectionEvent event) + throws FormProcessException { + + Objects.requireNonNull(asset); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); + + if (!(asset instanceof BinaryAsset)) { + throw new IllegalArgumentException(String.format( + "Provided asset is not an instance of '%s' (or a sub class) " + + "but is an instance of class '%s'.", + BinaryAsset.class.getName(), + asset.getClass().getName())); + } + + final BinaryAsset binaryAsset = (BinaryAsset) asset; + + binaryAsset + .getDescription() + .addValue(getSelectedLocale(state), + (String) description.getValue(state)); + + setFileData(event, binaryAsset); + } + + private void setFileData(final FormSectionEvent event, + final BinaryAsset binaryAsset) + throws FormProcessException { + + final File file = fileUpload.getFile(event); + final Path path = file.toPath(); + final byte[] data; + try { + data = Files.readAllBytes(path); + } catch (IOException ex) { + throw new FormProcessException(ex); + } + binaryAsset.setData(data); + binaryAsset.setSize(data.length); + + binaryAsset.setMimeType(fileUpload.getMimeType(event)); + } + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BookmarkForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BookmarkForm.java index fd9a08203..31eab23d5 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BookmarkForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/BookmarkForm.java @@ -134,10 +134,12 @@ public class BookmarkForm extends AssetForm { } @Override - protected Asset createAsset(final PageState state) + protected Asset createAsset(final FormSectionEvent event) throws FormProcessException { - Objects.requireNonNull(state); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); final Bookmark bookmark = new Bookmark(); @@ -158,11 +160,14 @@ public class BookmarkForm extends AssetForm { @Override - protected void updateAsset(final Asset asset, final PageState state) + protected void updateAsset(final Asset asset, + final FormSectionEvent event) throws FormProcessException { Objects.requireNonNull(asset); - Objects.requireNonNull(state); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); if (!(asset instanceof Bookmark)) { throw new IllegalArgumentException(String.format( diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/ExternalVideoAssetForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/ExternalVideoAssetForm.java index 428af4523..7b2f6044a 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/ExternalVideoAssetForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/ExternalVideoAssetForm.java @@ -21,6 +21,7 @@ package com.arsdigita.cms.ui.assets.forms; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.cms.ui.assets.AssetPane; import com.arsdigita.cms.ui.assets.AssetSearchWidget; import com.arsdigita.globalization.GlobalizedMessage; @@ -82,10 +83,12 @@ public class ExternalVideoAssetForm extends BookmarkForm { } @Override - protected Asset createAsset(final PageState state) + protected Asset createAsset(final FormSectionEvent event) throws FormProcessException { - Objects.requireNonNull(state); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); final ExternalVideoAsset externalVideoAsset = new ExternalVideoAsset(); @@ -114,11 +117,14 @@ public class ExternalVideoAssetForm extends BookmarkForm { } @Override - protected void updateAsset(final Asset asset, final PageState state) { + protected void updateAsset(final Asset asset, + final FormSectionEvent event) { Objects.requireNonNull(asset); - Objects.requireNonNull(state); + Objects.requireNonNull(event); + final PageState state = event.getPageState(); + if (!(asset instanceof ExternalVideoAsset)) { throw new IllegalArgumentException(String.format( "Provided asset is not an instance of class (or sub class of) " diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/LegalMetadataForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/LegalMetadataForm.java index 3893bdd03..0225a9cfb 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/LegalMetadataForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/LegalMetadataForm.java @@ -22,6 +22,7 @@ import com.arsdigita.bebop.BoxPanel; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.form.TextArea; import com.arsdigita.cms.ui.assets.AssetForm; import com.arsdigita.cms.ui.assets.AssetPane; @@ -53,7 +54,7 @@ public class LegalMetadataForm extends AssetForm { protected void addWidgets() { final BoxPanel panel = new BoxPanel(BoxPanel.VERTICAL); - + panel.add(new Label(new GlobalizedMessage( "cms.ui.assets.legalmetadata.rightsholder", CmsConstants.CMS_BUNDLE))); @@ -77,7 +78,7 @@ public class LegalMetadataForm extends AssetForm { CmsConstants.CMS_BUNDLE))); creator = new TextArea("legalmetadata-creator"); panel.add(creator); - + add(panel); } @@ -110,6 +111,7 @@ public class LegalMetadataForm extends AssetForm { @Override protected void showLocale(final PageState state) { + final Optional selectedAsset = getSelectedAsset(state); if (selectedAsset.isPresent()) { @@ -118,7 +120,8 @@ public class LegalMetadataForm extends AssetForm { "Selected asset is not a legal metadata"); } - final LegalMetadata legalMetadata = (LegalMetadata) selectedAsset.get(); + final LegalMetadata legalMetadata = (LegalMetadata) selectedAsset. + get(); rights.setValue(state, legalMetadata @@ -128,10 +131,12 @@ public class LegalMetadataForm extends AssetForm { } @Override - protected Asset createAsset(final PageState state) + protected Asset createAsset(final FormSectionEvent event) throws FormProcessException { - Objects.requireNonNull(state); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); final LegalMetadata legalMetadata = new LegalMetadata(); @@ -146,18 +151,20 @@ public class LegalMetadataForm extends AssetForm { } @Override - protected void updateAsset(final Asset asset, final PageState state) + protected void updateAsset(final Asset asset, + final FormSectionEvent event) throws FormProcessException { Objects.requireNonNull(asset); - Objects.requireNonNull(state); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); if (!(asset instanceof LegalMetadata)) { throw new IllegalArgumentException(String.format( "Provided asset is not an instance of '%s' (or a sub class) " + "but is an instance of class '%s'.", - LegalMetadata.class - .getName(), + LegalMetadata.class.getName(), asset.getClass().getName())); } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/SideNoteForm.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/SideNoteForm.java index 2944caf14..19a3aa7bf 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/SideNoteForm.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/forms/SideNoteForm.java @@ -21,6 +21,7 @@ package com.arsdigita.cms.ui.assets.forms; import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.event.FormSectionEvent; import com.arsdigita.bebop.form.TextArea; import com.arsdigita.cms.ui.assets.AssetForm; import com.arsdigita.cms.ui.assets.AssetPane; @@ -99,11 +100,13 @@ public class SideNoteForm extends AssetForm { } @Override - protected Asset createAsset(final PageState state) throws + protected Asset createAsset(final FormSectionEvent event) throws FormProcessException { - Objects.requireNonNull(state); + Objects.requireNonNull(event); + final PageState state = event.getPageState(); + final SideNote sideNote = new SideNote(); sideNote @@ -115,11 +118,14 @@ public class SideNoteForm extends AssetForm { } @Override - protected void updateAsset(final Asset asset, final PageState state) + protected void updateAsset(final Asset asset, + final FormSectionEvent event) throws FormProcessException { Objects.requireNonNull(asset); - Objects.requireNonNull(state); + Objects.requireNonNull(event); + + final PageState state = event.getPageState(); if (!(asset instanceof SideNote)) { throw new IllegalArgumentException(String.format( diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java index e6a46a12a..831b233be 100644 --- a/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/AdminServlet.java @@ -45,6 +45,7 @@ import org.libreccm.web.CcmApplication; import java.io.IOException; import javax.enterprise.inject.spi.CDI; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; @@ -142,6 +143,12 @@ public class AdminServlet extends BaseApplicationServlet { new Label(new GlobalizedMessage("ui.admin.tab.sysinfo.title", ADMIN_BUNDLE)), new SystemInformationTab()); + + final ServletContext servletContext = getServletContext(); + final String develMode = servletContext.getInitParameter("ccm.develmode"); + if (develMode != null && "true".equals(develMode.toLowerCase())) { + + } //page.add(new Label("admin")); adminPage.add(tabbedPane); diff --git a/ccm-core/src/main/java/com/arsdigita/ui/admin/JpqlConsole.java b/ccm-core/src/main/java/com/arsdigita/ui/admin/JpqlConsole.java new file mode 100644 index 000000000..a834ad223 --- /dev/null +++ b/ccm-core/src/main/java/com/arsdigita/ui/admin/JpqlConsole.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.ui.admin; + +import com.arsdigita.bebop.BoxPanel; +import com.arsdigita.bebop.Form; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.SaveCancelSection; +import com.arsdigita.bebop.SegmentedPanel; +import com.arsdigita.bebop.SimpleComponent; +import com.arsdigita.bebop.form.TextArea; +import com.arsdigita.globalization.GlobalizedMessage; +import com.arsdigita.toolbox.ui.LayoutPanel; +import com.arsdigita.xml.Element; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +/** + * + * @author Jens Pelzetter + */ +public class JpqlConsole extends LayoutPanel { + + private static final Logger LOGGER = LogManager.getLogger(JpqlConsole.class); + + private final Form queryForm; + private final TextArea queryArea; + + public JpqlConsole() { + super(); + + final SegmentedPanel panel = new SegmentedPanel(); + + queryForm = new Form("jpql-console-query-form"); + + queryArea = new TextArea("jpql-console-query-area"); + queryArea.setCols(132); + queryArea.setRows(42); + + final BoxPanel hpanel = new BoxPanel(BoxPanel.HORIZONTAL); + hpanel.add(new Label(new GlobalizedMessage( + "ui.admin.jpqlconsole.query.label", + AdminUiConstants.ADMIN_BUNDLE))); + hpanel.add(queryArea); + + final BoxPanel vpanel = new BoxPanel(BoxPanel.VERTICAL); + vpanel.add(hpanel); + final SaveCancelSection saveCancelSection = new SaveCancelSection(); + saveCancelSection.getSaveButton().setLabel( + new GlobalizedMessage("ui.admin.jpqlconsole.query.execute", + AdminUiConstants.ADMIN_BUNDLE)); + saveCancelSection.getCancelButton().setLabel( + new GlobalizedMessage("ui.admin.jpqlconsole.query.clear", + AdminUiConstants.ADMIN_BUNDLE)); + vpanel.add(saveCancelSection); + + queryForm.add(hpanel); + + panel.addSegment(new Label(new GlobalizedMessage( + "ui.admin.jpqlconsole.query.segment.title", + AdminUiConstants.ADMIN_BUNDLE)), + queryForm); + + setBody(panel); + } + + private class QueryResults extends SimpleComponent { + + private List results; + + public List getResults() { + return results; + } + + public void setResults(final List results) { + this.results = results; + } + + private List getProperties(final List results) + throws IntrospectionException { + + final Set propertyDescriptors = new HashSet<>(); + + for (final Object obj : results) { + final PropertyDescriptor[] properties = Introspector + .getBeanInfo(obj.getClass()).getPropertyDescriptors(); + + for (final PropertyDescriptor property : properties) { + propertyDescriptors.add(property); + } + } + + final List propertiesList + = new ArrayList<>(propertyDescriptors); + propertiesList.sort((prop1, prop2) -> { + return prop1.getName().compareTo(prop2.getName()); + }); + + return propertiesList; + } + + @Override + public void generateXML(final PageState state, + final Element parent) { + + final Element queryResults = parent + .newChildElement("bebop:query-results", BEBOP_XML_NS); + + // Find all properties in the results + final List properties; + try { + properties = getProperties(results); + } catch (IntrospectionException ex) { + queryArea.addError(new GlobalizedMessage( + "ui.admin.jpqlconsole.failed_to_render_results", + AdminUiConstants.ADMIN_BUNDLE)); + LOGGER.error("Failed to render results.", ex); + return; + } + + final Element columns = queryResults + .newChildElement("bebop:query-result-columns", BEBOP_XML_NS); + for (final PropertyDescriptor property : properties) { + final Element column = columns + .newChildElement("bebop:query-result-column", BEBOP_XML_NS); + column.setText(property.getName()); + } + + final Element resultList = queryResults + .newChildElement("bebop:query-result-list", BEBOP_XML_NS); + for(final Object obj : results) { + for(final PropertyDescriptor property : properties) { + final Method readMethod = property.getReadMethod(); + + + } + } + + } + + } + +} diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties index 910fc3f90..ace0e7de7 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources.properties @@ -552,3 +552,6 @@ ui.admin.tab.users_groups_roles.role_members=Members ui.admin.tab.users_groups_roles.role_permissions=Permissions ui.admin.tab.users_groups_roles.role_details.save=Save ui.admin.tab.users_groups_roles.role_details.cancel=Cancel +ui.admin.jpqlconsole.query.label=Query +ui.admin.jpqlconsole.query.execute=Execute +ui.admin.jpqlconsole.query.clear=Clear diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties index c876208ca..bd7ccad64 100644 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_de.properties @@ -556,3 +556,6 @@ ui.admin.tab.users_groups_roles.role_members=Mitglieder ui.admin.tab.users_groups_roles.role_permissions=Berechtigungen ui.admin.tab.users_groups_roles.role_details.save=Speichern ui.admin.tab.users_groups_roles.role_details.cancel=Abbrechen +ui.admin.jpqlconsole.query.label=Abfrage +ui.admin.jpqlconsole.query.execute=Ausf\u00fchren +ui.admin.jpqlconsole.query.clear=Zur\u00fccksetzen diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties index 1f8579efe..d5acc09d7 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_en.properties @@ -549,3 +549,6 @@ ui.admin.tab.users_groups_roles.role_members=Members ui.admin.tab.users_groups_roles.role_permissions=Permissions ui.admin.tab.users_groups_roles.role_details.save=Save ui.admin.tab.users_groups_roles.role_details.cancel=Cancel +ui.admin.jpqlconsole.query.label=Query +ui.admin.jpqlconsole.query.execute=Excute +ui.admin.jpqlconsole.query.clear=Clear diff --git a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties index 0cb6be9ec..40476d17a 100755 --- a/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties +++ b/ccm-core/src/main/resources/com/arsdigita/ui/admin/AdminResources_fr.properties @@ -540,3 +540,6 @@ ui.admin.tab.users_groups_roles.role_members=Members ui.admin.tab.users_groups_roles.role_permissions=Permissions ui.admin.tab.users_groups_roles.role_details.save=Save ui.admin.tab.users_groups_roles.role_details.cancel=Cancel +ui.admin.jpqlconsole.query.label=Query +ui.admin.jpqlconsole.query.execute=Execute +ui.admin.jpqlconsole.query.clear=Clear