Search in sources :

Example 1 with CrudConfiguration

use of com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration in project Portofino by ManyDesigns.

the class CrudAction method saveConfiguration.

@Override
protected boolean saveConfiguration(Object configuration) {
    CrudConfiguration crudConfiguration = (CrudConfiguration) configuration;
    List<SelectionProviderReference> sps = new ArrayList<>(crudConfiguration.getSelectionProviders());
    crudConfiguration.getSelectionProviders().clear();
    crudConfiguration.persistence = persistence;
    crudConfiguration.init();
    sps.forEach(sp -> {
        ForeignKey fk = DatabaseLogic.findForeignKeyByName(crudConfiguration.getActualTable(), sp.getSelectionProviderName());
        if (fk != null) {
            sp.setForeignKeyName(sp.getSelectionProviderName());
            sp.setSelectionProviderName(null);
        }
        if (sp.getSelectionProviderName() != null || sp.getForeignKeyName() != null) {
            crudConfiguration.getSelectionProviders().add(sp);
        }
    });
    List<CrudProperty> existingProperties = this.crudConfiguration.getProperties();
    List<CrudProperty> configuredProperties = crudConfiguration.getProperties();
    List<CrudProperty> newProperties = configuredProperties.stream().map(p1 -> {
        Optional<CrudProperty> maybeP2 = existingProperties.stream().filter(p2 -> p1.getName().equals(p2.getName())).findFirst();
        CrudProperty p2 = maybeP2.orElse(new CrudProperty());
        p2.setName(p1.getName());
        p2.setEnabled(p1.isEnabled());
        p2.setInsertable(p1.isInsertable());
        p2.setInSummary(p1.isInSummary());
        p2.setLabel(p1.getLabel());
        p2.setSearchable(p1.isSearchable());
        p2.setUpdatable(p1.isUpdatable());
        return p2;
    }).collect(Collectors.toList());
    crudConfiguration.setProperties(newProperties);
    return super.saveConfiguration(crudConfiguration);
}
Also used : Persistence(com.manydesigns.portofino.persistence.Persistence) StringUtils(org.apache.commons.lang.StringUtils) java.util(java.util) TableCriteria(com.manydesigns.portofino.persistence.TableCriteria) ResourceActionName(com.manydesigns.portofino.resourceactions.ResourceActionName) CrudConfiguration(com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration) QueryStringWithParameters(com.manydesigns.elements.text.QueryStringWithParameters) LoggerFactory(org.slf4j.LoggerFactory) Session(org.hibernate.Session) Autowired(org.springframework.beans.factory.annotation.Autowired) Insertable(com.manydesigns.elements.annotations.Insertable) ConfigurationClass(com.manydesigns.portofino.resourceactions.annotations.ConfigurationClass) SupportsPermissions(com.manydesigns.portofino.security.SupportsPermissions) PlainSelect(net.sf.jsqlparser.statement.select.PlainSelect) JSQLParserException(net.sf.jsqlparser.JSQLParserException) ElementsThreadLocals(com.manydesigns.elements.ElementsThreadLocals) DatabaseLogic(com.manydesigns.portofino.model.database.DatabaseLogic) TableAccessor(com.manydesigns.portofino.reflection.TableAccessor) ClassAccessor(com.manydesigns.elements.reflection.ClassAccessor) Function(net.sf.jsqlparser.expression.Function) ExpressionList(net.sf.jsqlparser.expression.operators.relational.ExpressionList) PropertyAccessor(com.manydesigns.elements.reflection.PropertyAccessor) Table(com.manydesigns.portofino.model.database.Table) SelectItem(net.sf.jsqlparser.statement.select.SelectItem) QueryUtils(com.manydesigns.portofino.persistence.QueryUtils) SelectionProviderReference(com.manydesigns.portofino.resourceactions.crud.configuration.database.SelectionProviderReference) AccessLevel(com.manydesigns.portofino.security.AccessLevel) Updatable(com.manydesigns.elements.annotations.Updatable) Logger(org.slf4j.Logger) ConstraintViolationException(org.hibernate.exception.ConstraintViolationException) CrudProperty(com.manydesigns.portofino.resourceactions.crud.configuration.CrudProperty) RequiresPermissions(com.manydesigns.portofino.security.RequiresPermissions) Collectors(java.util.stream.Collectors) IdStrategy(com.manydesigns.portofino.persistence.IdStrategy) RequestMessages(com.manydesigns.elements.messages.RequestMessages) Serializable(java.io.Serializable) PkHelper(com.manydesigns.portofino.util.PkHelper) SelectExpressionItem(net.sf.jsqlparser.statement.select.SelectExpressionItem) ScriptTemplate(com.manydesigns.portofino.resourceactions.annotations.ScriptTemplate) Database(com.manydesigns.portofino.model.database.Database) Select(net.sf.jsqlparser.statement.select.Select) ForeignKey(com.manydesigns.portofino.model.database.ForeignKey) StringReader(java.io.StringReader) ActionInstance(com.manydesigns.portofino.resourceactions.ActionInstance) NotNull(org.jetbrains.annotations.NotNull) CCJSqlParserManager(net.sf.jsqlparser.parser.CCJSqlParserManager) SelectionProviderReference(com.manydesigns.portofino.resourceactions.crud.configuration.database.SelectionProviderReference) CrudProperty(com.manydesigns.portofino.resourceactions.crud.configuration.CrudProperty) ForeignKey(com.manydesigns.portofino.model.database.ForeignKey) CrudConfiguration(com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration)

Example 2 with CrudConfiguration

use of com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration in project Portofino by ManyDesigns.

the class CrudActionTest method testBlobs.

public void testBlobs() throws Exception {
    MutableHttpServletRequest req = new MutableHttpServletRequest();
    ElementsThreadLocals.setMultipart(req);
    req.getServletContext().setInitParameter("portofino.api.root", "http://fake");
    req.makeMultipart();
    Column column = DatabaseLogic.findColumnByName(persistence.getModel(), "jpetstore", "PUBLIC", "PRODUCT", "DESCN");
    Annotation ann = new Annotation(column, FileBlob.class.getName());
    column.getAnnotations().add(ann);
    persistence.initModel();
    CrudAction crudAction = new CrudAction() {

        public void commitTransaction() {
            super.commitTransaction();
            session.beginTransaction();
        }

        @NotNull
        @Override
        protected ClassAccessor filterAccordingToPermissions(ClassAccessor classAccessor) {
            // Let's ignore Shiro
            return classAccessor;
        }

        @Override
        protected String getUrlEncoding() {
            return PortofinoProperties.URL_ENCODING_DEFAULT;
        }
    };
    CrudConfiguration configuration = new CrudConfiguration();
    configuration.setDatabase("jpetstore");
    configuration.setQuery("from product");
    String metaFilenamePattern = "blob-{0}.properties";
    String dataFilenamePattern = "blob-{0}.data";
    crudAction.blobManager = new HierarchicalBlobManager(new File(System.getProperty("java.io.tmpdir")), metaFilenamePattern, dataFilenamePattern);
    CrudProperty property = new CrudProperty();
    property.setName("productid");
    property.setEnabled(true);
    property.setInsertable(true);
    property.setUpdatable(true);
    configuration.getProperties().add(property);
    property = new CrudProperty();
    property.setName("category");
    property.setEnabled(true);
    property.setInsertable(true);
    property.setUpdatable(true);
    configuration.getProperties().add(property);
    property = new CrudProperty();
    property.setName("descn");
    property.setEnabled(true);
    property.setInsertable(true);
    property.setUpdatable(true);
    configuration.getProperties().add(property);
    property = new CrudProperty();
    property.setName("name");
    property.setEnabled(true);
    property.setInsertable(true);
    property.setUpdatable(true);
    ann = new Annotation(column, Required.class.getName());
    ann.getProperties().add(new Property("value", "true"));
    property.getAnnotations().add(ann);
    configuration.getProperties().add(property);
    configuration.persistence = persistence;
    configuration.init();
    ActionInstance actionInstance = new ActionInstance(null, null, new ActionDescriptor(), CrudAction.class);
    actionInstance.setConfiguration(configuration);
    actionInstance.getParameters().add("1");
    ActionContext actionContext = new ActionContext();
    actionContext.setRequest(req);
    actionContext.setActionPath("");
    actionContext.setServletContext(req.getServletContext());
    req.setParameter("productid", "1");
    Map category = (Map) persistence.getSession("jpetstore").createQuery("from category").list().get(0);
    req.setParameter("category", (String) category.get("catid"));
    crudAction.persistence = persistence;
    crudAction.setContext(actionContext);
    crudAction.setActionInstance(actionInstance);
    crudAction.init();
    crudAction.setupForm(Mode.CREATE);
    Field descnField = crudAction.getForm().findFieldByPropertyName("descn");
    assertNotNull(descnField);
    assertTrue(descnField instanceof FileBlobField);
    File tmpFile = File.createTempFile("blob", "blob");
    DiskFileItem fileItem = new DiskFileItem("descn", "application/octet-stream", false, tmpFile.getName(), 0, tmpFile.getParentFile()) {

        @Override
        public void delete() {
        // Do nothing as we want to reuse this
        }
    };
    OutputStream os = fileItem.getOutputStream();
    IOUtils.write("some test data", os, req.getCharacterEncoding());
    req.addFileItem("descn", fileItem);
    req.setParameter("descn_operation", AbstractBlobField.UPLOAD_MODIFY);
    crudAction.httpPostMultipart();
    assertFalse(crudAction.form.validate());
    AbstractBlobField blobField = (AbstractBlobField) crudAction.form.findFieldByPropertyName("descn");
    assertNotNull(blobField.getValue());
    assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
    assertEquals(fileItem.getSize(), blobField.getValue().getSize());
    try {
        crudAction.getBlobManager().loadMetadata(new Blob(blobField.getValue().getCode()));
        fail("The blob was saved despite validation failing");
    } catch (Exception e) {
    }
    crudAction.object = null;
    req.setParameter(blobField.getCodeInputName(), blobField.getValue().getCode());
    req.setParameter("name", "name");
    req.setParameter("productid", "1");
    req.setParameter("category", "BIRDS");
    crudAction.httpPostMultipart();
    assertTrue(crudAction.form.validate());
    blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
    assertNotNull(blobField.getValue());
    // This is necessary because the crud might reload the form
    crudAction.blobManager.loadMetadata(blobField.getValue());
    assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
    assertEquals(fileItem.getSize(), blobField.getValue().getSize());
    try {
        crudAction.blobManager.loadMetadata(new Blob(blobField.getValue().getCode()));
    } catch (IOException e) {
        e.printStackTrace();
        fail("The blob was not saved");
    }
    crudAction.httpPutMultipart();
    assertTrue(crudAction.form.validate());
    blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
    assertNotNull(blobField.getValue());
    // This is necessary because the crud might reload the form
    crudAction.blobManager.loadMetadata(blobField.getValue());
    assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
    String oldBlobCode = blobField.getValue().getCode();
    assertEquals(fileItem.getSize(), blobField.getValue().getSize());
    req.setParameter("descn_operation", FileBlobField.UPLOAD_MODIFY);
    req.setFileItem("descn", fileItem);
    crudAction.httpPutMultipart();
    assertTrue(crudAction.form.validate());
    blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
    assertNotNull(blobField.getValue());
    // This is necessary because the crud might reload the form
    crudAction.blobManager.loadMetadata(blobField.getValue());
    assertEquals(tmpFile.getName(), blobField.getValue().getFilename());
    String newBlobCode = blobField.getValue().getCode();
    assertNotEquals(oldBlobCode, newBlobCode);
    crudAction.blobManager.loadMetadata(new Blob(newBlobCode));
    try {
        crudAction.blobManager.loadMetadata(new Blob(oldBlobCode));
        fail("The blob " + oldBlobCode + " should have been deleted");
    } catch (IOException e) {
    // Ok
    }
    Session session = persistence.getSession("jpetstore");
    session.flush();
    Object id = ((Map) crudAction.object).get("productid");
    int qres = session.createSQLQuery("update product set descn = 'illegal' where productid = :id").setParameter("id", id).executeUpdate();
    assertEquals(1, qres);
    session.flush();
    session.getTransaction().commit();
    session.clear();
    session.beginTransaction();
    // Force loading the object from the DB
    crudAction.getParameters().add(id.toString());
    crudAction.parametersAcquired();
    crudAction.setupForm(Mode.VIEW);
    crudAction.form.readFromObject(crudAction.object);
    BlobUtils.loadBlobs(crudAction.form, crudAction.getBlobManager(), false);
    blobField = (FileBlobField) crudAction.form.findFieldByPropertyName("descn");
    assertNotNull(blobField.getValue());
    assertNotNull(blobField.getBlobError());
    assertNull(blobField.getValue().getFilename());
    qres = session.createSQLQuery("update product set descn = :blobCode where productid = :id").setParameter("id", id).setParameter("blobCode", newBlobCode).executeUpdate();
    assertEquals(1, qres);
    session.flush();
    session.getTransaction().commit();
    session.clear();
    session.beginTransaction();
    // Force reload
    crudAction.parametersAcquired();
    crudAction.httpDelete(Collections.emptyList());
    try {
        crudAction.blobManager.loadMetadata(new Blob(newBlobCode));
        fail("The blob " + newBlobCode + " should have been deleted");
    } catch (IOException e) {
    // Ok
    }
}
Also used : FileBlobField(com.manydesigns.elements.fields.FileBlobField) ActionDescriptor(com.manydesigns.portofino.actions.ActionDescriptor) OutputStream(java.io.OutputStream) Field(com.manydesigns.elements.fields.Field) FileBlobField(com.manydesigns.elements.fields.FileBlobField) AbstractBlobField(com.manydesigns.elements.fields.AbstractBlobField) Column(com.manydesigns.portofino.model.database.Column) CrudProperty(com.manydesigns.portofino.resourceactions.crud.configuration.CrudProperty) AbstractBlobField(com.manydesigns.elements.fields.AbstractBlobField) Property(com.manydesigns.portofino.model.Property) CrudProperty(com.manydesigns.portofino.resourceactions.crud.configuration.CrudProperty) CrudConfiguration(com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration) DiskFileItem(org.apache.commons.fileupload.disk.DiskFileItem) Blob(com.manydesigns.elements.blobs.Blob) FileBlob(com.manydesigns.elements.annotations.FileBlob) FileBlob(com.manydesigns.elements.annotations.FileBlob) MutableHttpServletRequest(com.manydesigns.elements.servlet.MutableHttpServletRequest) IOException(java.io.IOException) ActionContext(com.manydesigns.portofino.resourceactions.ActionContext) Annotation(com.manydesigns.portofino.model.Annotation) SQLException(java.sql.SQLException) IOException(java.io.IOException) ActionInstance(com.manydesigns.portofino.resourceactions.ActionInstance) ClassAccessor(com.manydesigns.elements.reflection.ClassAccessor) HierarchicalBlobManager(com.manydesigns.elements.blobs.HierarchicalBlobManager) FileObject(org.apache.commons.vfs2.FileObject) File(java.io.File) Map(java.util.Map) Session(org.hibernate.Session)

Example 3 with CrudConfiguration

use of com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration in project Portofino by ManyDesigns.

the class UpstairsAction method createCrudAction.

protected ActionDescriptor createCrudAction(ConnectionProvider connectionProvider, FileObject dir, Table table, String query, Template template, Map<String, String> bindings, Table userTable, Column userPasswordColumn, List<Map> createdPages, int depth) throws Exception {
    if (dir.exists()) {
        RequestMessages.addWarningMessage(ElementsThreadLocals.getText("directory.exists.page.not.created._", dir.getName().getPath()));
    } else {
        dir.createFolder();
        logger.info("Creating CRUD action {}", dir.getName().getPath());
        CrudConfiguration configuration = new CrudConfiguration();
        configuration.setDatabase(table.getDatabaseName());
        configuration.setupDefaults();
        configuration.setQuery(query);
        String variable = table.getActualEntityName();
        configuration.setVariable(variable);
        detectLargeResultSet(connectionProvider, table, configuration);
        configuration.setName(table.getActualEntityName());
        int summ = 0;
        String linkToParentProperty = bindings.get("linkToParentProperty");
        for (Column column : table.getColumns()) {
            String name = column.getColumnName();
            boolean isPassword = column.equals(userPasswordColumn) || (column.getActualJavaType() == String.class && ("password".equalsIgnoreCase(name) || "pwd".equalsIgnoreCase(name)));
            summ = setupColumn(connectionProvider, column, configuration, summ, linkToParentProperty, isPassword);
        }
        ActionLogic.saveConfiguration(dir, configuration);
        ActionDescriptor action = new ActionDescriptor();
        ActionLogic.saveActionDescriptor(dir, action);
        FileObject actionFile = dir.resolveFile("action.groovy");
        try (Writer fileWriter = new OutputStreamWriter(actionFile.getContent().getOutputStream())) {
            template.make(bindings).writeTo(fileWriter);
        }
        logger.debug("Creating _detail directory");
        FileObject detailDir = dir.resolveFile(ActionInstance.DETAIL);
        if (detailDir.exists() && detailDir.getType() != FileType.FOLDER) {
            logger.warn("Invalid detail directory {}", detailDir.getName().getPath());
            RequestMessages.addWarningMessage(ElementsThreadLocals.getText("invalid.detail.directory", detailDir.getName().getPath()));
        } else {
            detailDir.createFolder();
        }
        String path = dir.getName().getBaseName();
        // two because of _detail
        FileObject parent = dir.getParent().getParent();
        for (int i = 1; i < depth; i++) {
            path = parent.getName().getBaseName() + "/" + ActionInstance.DETAIL + "/" + path;
            parent = parent.getParent().getParent();
        }
        Map<String, Object> pageInfo = new HashMap<>();
        pageInfo.put("path", path);
        pageInfo.put("detail", depth > 1);
        pageInfo.put("type", "crud");
        pageInfo.put("title", Util.guessToWords(dir.getName().getBaseName()));
        createdPages.add(pageInfo);
        if (depth < maxDepth) {
            List<Reference> children = computeChildren(table);
            for (Reference ref : children) {
                createChildCrudAction(connectionProvider, dir, template, variable, children, ref, userTable, userPasswordColumn, createdPages, depth);
            }
        }
        return action;
    }
    return null;
}
Also used : ActionDescriptor(com.manydesigns.portofino.actions.ActionDescriptor) OutputStreamWriter(java.io.OutputStreamWriter) FileObject(org.apache.commons.vfs2.FileObject) FileObject(org.apache.commons.vfs2.FileObject) CrudConfiguration(com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter)

Aggregations

CrudConfiguration (com.manydesigns.portofino.resourceactions.crud.configuration.database.CrudConfiguration)3 ClassAccessor (com.manydesigns.elements.reflection.ClassAccessor)2 ActionDescriptor (com.manydesigns.portofino.actions.ActionDescriptor)2 ActionInstance (com.manydesigns.portofino.resourceactions.ActionInstance)2 CrudProperty (com.manydesigns.portofino.resourceactions.crud.configuration.CrudProperty)2 Session (org.hibernate.Session)2 ElementsThreadLocals (com.manydesigns.elements.ElementsThreadLocals)1 FileBlob (com.manydesigns.elements.annotations.FileBlob)1 Insertable (com.manydesigns.elements.annotations.Insertable)1 Updatable (com.manydesigns.elements.annotations.Updatable)1 Blob (com.manydesigns.elements.blobs.Blob)1 HierarchicalBlobManager (com.manydesigns.elements.blobs.HierarchicalBlobManager)1 AbstractBlobField (com.manydesigns.elements.fields.AbstractBlobField)1 Field (com.manydesigns.elements.fields.Field)1 FileBlobField (com.manydesigns.elements.fields.FileBlobField)1 RequestMessages (com.manydesigns.elements.messages.RequestMessages)1 PropertyAccessor (com.manydesigns.elements.reflection.PropertyAccessor)1 MutableHttpServletRequest (com.manydesigns.elements.servlet.MutableHttpServletRequest)1 QueryStringWithParameters (com.manydesigns.elements.text.QueryStringWithParameters)1 Annotation (com.manydesigns.portofino.model.Annotation)1