Search in sources :

Example 16 with PropertyAccessor

use of com.manydesigns.elements.reflection.PropertyAccessor in project Portofino by ManyDesigns.

the class QueryUtils method getObjectByPk.

/**
 * Loads an object by primary key. It also verifies that the object falls within the results of a given query.
 * @param persistence the persistence object
 * @param database the database (connection provider)
 * @param entityName the name of the entity to load
 * @param pk the primary key object
 * @param hqlQueryString the query (where condition) that the object must fulfill
 * @param rootObject the OGNL rootFactory object against which to evaluate the query string.
 * @return the loaded object, or null if an object with that key does not exist or falls outside the query.
 */
public static Object getObjectByPk(Persistence persistence, String database, String entityName, Serializable pk, String hqlQueryString, Object rootObject) {
    TableAccessor table = persistence.getTableAccessor(database, entityName);
    List<Object> result;
    PropertyAccessor[] keyProperties = table.getKeyProperties();
    OgnlHqlFormat hqlFormat = OgnlHqlFormat.create(hqlQueryString);
    String formatString = hqlFormat.getFormatString();
    Object[] ognlParameters = hqlFormat.evaluateOgnlExpressions(rootObject);
    int p = ognlParameters.length;
    Object[] parameters = new Object[p + keyProperties.length];
    System.arraycopy(ognlParameters, 0, parameters, 0, p);
    try {
        PlainSelect parsedQuery = parseQuery(new CCJSqlParserManager(), formatString);
        if (parsedQuery.getWhere() == null) {
            return getObjectByPk(persistence, database, entityName, pk);
        }
        Alias mainEntityAlias = getEntityAlias(entityName, parsedQuery);
        net.sf.jsqlparser.schema.Table mainEntityTable;
        if (mainEntityAlias != null) {
            mainEntityTable = new net.sf.jsqlparser.schema.Table(null, mainEntityAlias.getName());
        } else {
            mainEntityTable = new net.sf.jsqlparser.schema.Table();
        }
        for (int i = 0; i < keyProperties.length; i++) {
            PropertyAccessor propertyAccessor = keyProperties[i];
            EqualsTo condition = new EqualsTo();
            parsedQuery.setWhere(new AndExpression(condition, new Parenthesis(parsedQuery.getWhere())));
            net.sf.jsqlparser.schema.Column column = new net.sf.jsqlparser.schema.Column(mainEntityTable, propertyAccessor.getName());
            condition.setLeftExpression(column);
            JdbcNamedParameter jdbcParameter = new JdbcNamedParameter();
            jdbcParameter.setName("p" + (p + i + 1));
            condition.setRightExpression(jdbcParameter);
            parameters[p + i] = propertyAccessor.get(pk);
        }
        String fullQueryString = parsedQuery.toString();
        if (fullQueryString.toLowerCase().startsWith(FAKE_SELECT_PREFIX)) {
            fullQueryString = fullQueryString.substring(FAKE_SELECT_PREFIX.length());
        }
        Session session = persistence.getSession(database);
        result = runHqlQuery(session, fullQueryString, parameters);
        if (result != null && !result.isEmpty()) {
            return result.get(0);
        } else {
            return null;
        }
    } catch (JSQLParserException e) {
        throw new Error(e);
    }
}
Also used : JdbcNamedParameter(net.sf.jsqlparser.expression.JdbcNamedParameter) Parenthesis(net.sf.jsqlparser.expression.Parenthesis) AndExpression(net.sf.jsqlparser.expression.operators.conditional.AndExpression) TableAccessor(com.manydesigns.portofino.reflection.TableAccessor) CCJSqlParserManager(net.sf.jsqlparser.parser.CCJSqlParserManager) PropertyAccessor(com.manydesigns.elements.reflection.PropertyAccessor) JSQLParserException(net.sf.jsqlparser.JSQLParserException) OgnlHqlFormat(com.manydesigns.elements.text.OgnlHqlFormat) Alias(net.sf.jsqlparser.expression.Alias) EqualsTo(net.sf.jsqlparser.expression.operators.relational.EqualsTo) Session(org.hibernate.Session)

Example 17 with PropertyAccessor

use of com.manydesigns.elements.reflection.PropertyAccessor in project Portofino by ManyDesigns.

the class QueryUtils method getRelatedObjects.

/**
 * Navigates a ...-to-many relationship returning the list of objects associated with a given entity.
 * @param persistence the persistence object
 * @param databaseName the name of the database (connection provider)
 * @param entityName the type (entity name) of the master object
 * @param obj the master object
 * @param oneToManyRelationshipName the name of the relationship to navigate
 * @return the list of associated objects
 */
@SuppressWarnings({ "unchecked" })
public static List<Object> getRelatedObjects(Persistence persistence, String databaseName, String entityName, Object obj, String oneToManyRelationshipName) {
    Model model = persistence.getModel();
    ForeignKey relationship = DatabaseLogic.findOneToManyRelationship(model, databaseName, entityName, oneToManyRelationshipName);
    if (relationship == null) {
        throw new IllegalArgumentException("Relationship not defined: " + oneToManyRelationshipName);
    }
    Table fromTable = relationship.getFromTable();
    Session session = persistence.getSession(fromTable.getDatabaseName());
    ClassAccessor toAccessor = persistence.getTableAccessor(databaseName, entityName);
    try {
        CriteriaDefinition criteria = createCriteria(session, fromTable);
        List<Predicate> where = new ArrayList<>();
        for (Reference reference : relationship.getReferences()) {
            Column fromColumn = reference.getActualFromColumn();
            Column toColumn = reference.getActualToColumn();
            PropertyAccessor toPropertyAccessor = toAccessor.getProperty(toColumn.getActualPropertyName());
            Object toValue = toPropertyAccessor.get(obj);
            where.add(criteria.builder.equal(criteria.root.get(fromColumn.getActualPropertyName()), toValue));
        }
        return session.createQuery(criteria.query.where(where.toArray(new Predicate[0]))).list();
    } catch (Throwable e) {
        String msg = String.format("Cannot access relationship %s on entity %s.%s", oneToManyRelationshipName, databaseName, entityName);
        logger.warn(msg, e);
    }
    return null;
}
Also used : PropertyAccessor(com.manydesigns.elements.reflection.PropertyAccessor) Predicate(javax.persistence.criteria.Predicate) ClassAccessor(com.manydesigns.elements.reflection.ClassAccessor) Model(com.manydesigns.portofino.model.Model) Session(org.hibernate.Session)

Example 18 with PropertyAccessor

use of com.manydesigns.elements.reflection.PropertyAccessor in project Portofino by ManyDesigns.

the class SelectionProviderLogic method createSelectionProvider.

public static DefaultSelectionProvider createSelectionProvider(String name, Collection objects, Class objectClass, @Nullable TextFormat[] textFormats, String[] propertyNames) {
    ClassAccessor classAccessor = JavaClassAccessor.getClassAccessor(objectClass);
    PropertyAccessor[] propertyAccessors = new PropertyAccessor[propertyNames.length];
    for (int i = 0; i < propertyNames.length; i++) {
        String currentName = propertyNames[i];
        try {
            PropertyAccessor propertyAccessor = classAccessor.getProperty(currentName);
            propertyAccessors[i] = propertyAccessor;
        } catch (Throwable e) {
            String msg = MessageFormat.format("Could not access property: {0}", currentName);
            logger.warn(msg, e);
            throw new IllegalArgumentException(msg, e);
        }
    }
    return createSelectionProvider(name, objects, propertyAccessors, textFormats);
}
Also used : PropertyAccessor(com.manydesigns.elements.reflection.PropertyAccessor) JavaClassAccessor(com.manydesigns.elements.reflection.JavaClassAccessor) ClassAccessor(com.manydesigns.elements.reflection.ClassAccessor)

Example 19 with PropertyAccessor

use of com.manydesigns.elements.reflection.PropertyAccessor in project Portofino by ManyDesigns.

the class ManyToManyAction method init.

@Override
public Object init() {
    preparePage();
    if (m2mConfiguration == null || m2mConfiguration.getActualRelationTable() == null || m2mConfiguration.getActualManyTable() == null) {
        logger.error("Configuration is null or relation/many table not found (check previous log messages)");
        // TODO WebApplicationException instead?
        return this;
    }
    Table table = m2mConfiguration.getActualRelationTable();
    relationTableAccessor = new TableAccessor(table);
    manyTableAccessor = new TableAccessor(m2mConfiguration.getActualManyTable());
    if (StringUtils.isBlank(m2mConfiguration.getActualOnePropertyName())) {
        logger.error("One property name not set");
        return this;
    }
    String expression = m2mConfiguration.getOneExpression();
    if (!StringUtils.isBlank(expression)) {
        // Set primary key
        OgnlContext ognlContext = ElementsThreadLocals.getOgnlContext();
        // TODO handle exception
        onePk = OgnlUtils.getValueQuietly(expression, ognlContext, this);
        correctlyConfigured = true;
    } else {
        assert !StringUtils.isBlank(m2mConfiguration.getActualOnePropertyName());
        // Setup "one" selection
        SelectionProviderReference oneSelectionProvider = m2mConfiguration.getOneSelectionProvider();
        if (oneSelectionProvider != null) {
            ModelSelectionProvider actualSelectionProvider = oneSelectionProvider.getActualSelectionProvider();
            if (!(actualSelectionProvider instanceof DatabaseSelectionProvider)) {
                logger.warn("Selection provider {} not supported", actualSelectionProvider);
                return this;
            }
            TableAccessor tableAccessor = new TableAccessor(m2mConfiguration.getActualRelationTable());
            PropertyAccessor onePkAccessor = null;
            try {
                onePkAccessor = tableAccessor.getProperty(m2mConfiguration.getActualOnePropertyName());
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            }
            if (onePkAccessor == null) {
                logger.warn("Not a property: {}", m2mConfiguration.getActualOnePropertyName());
                return this;
            }
            String databaseName = m2mConfiguration.getActualOneDatabase().getDatabaseName();
            DatabaseSelectionProvider sp = (DatabaseSelectionProvider) actualSelectionProvider;
            DefaultSelectionProvider selectionProvider;
            String name = sp.getName();
            String hql = sp.getHql();
            if (StringUtils.isNotEmpty(hql)) {
                selectionProvider = createSelectionProviderFromHql(name, databaseName, hql, DisplayMode.DROPDOWN, SearchDisplayMode.DROPDOWN);
                if (sp instanceof ForeignKey) {
                    selectionProvider.sortByLabel();
                }
            } else {
                logger.warn("ModelSelection provider '{}': unsupported query", name);
                return this;
            }
            Object myInstance = tableAccessor.newInstance();
            oneSelectField = new SelectField(onePkAccessor, selectionProvider, Mode.EDIT, "__");
            oneSelectField.setRequired(false);
            oneSelectField.readFromRequest(context.getRequest());
            oneSelectField.writeToObject(myInstance);
            onePk = onePkAccessor.get(myInstance);
            correctlyConfigured = true;
        }
    }
    return this;
}
Also used : PropertyAccessor(com.manydesigns.elements.reflection.PropertyAccessor) SelectField(com.manydesigns.elements.fields.SelectField) OgnlContext(ognl.OgnlContext) TableAccessor(com.manydesigns.portofino.reflection.TableAccessor) SelectionProviderReference(com.manydesigns.portofino.resourceactions.m2m.configuration.SelectionProviderReference) JSONObject(org.json.JSONObject)

Example 20 with PropertyAccessor

use of com.manydesigns.elements.reflection.PropertyAccessor in project Portofino by ManyDesigns.

the class ManyToManyAction method httpPostJson.

/**
 * Handles object creation via REST.
 * @param jsonObject the object (in serialized JSON form)
 * @since 4.2.1
 * @return the created object as JSON (in a JAX-RS Response).
 * @throws Exception only to make the compiler happy. Nothing should be thrown in normal operation. If this method throws, it is probably a bug.
 */
@POST
@RequiresPermissions(permissions = ManyToManyAction.PERMISSION_UPDATE)
@Produces(MimeTypes.APPLICATION_JSON_UTF8)
@Consumes(MimeTypes.APPLICATION_JSON_UTF8)
public Response httpPostJson(String jsonObject) throws Exception {
    JSONObject obj = new JSONObject(jsonObject);
    logger.debug(jsonObject);
    if (!correctlyConfigured) {
        return Response.serverError().entity(configurationForm).build();
    }
    for (Object key : obj.keySet()) {
        try {
            loadOnePk(key);
        } catch (Exception e) {
            logger.error("Cannot get key " + key, e);
        }
        JSONArray selectedKeysJson = obj.getJSONArray(onePk.toString());
        for (int i = 0; i < selectedKeysJson.length(); i++) {
            selectedPrimaryKeys.add(selectedKeysJson.get(i).toString());
        }
        try {
            loadAssociations();
        } catch (Exception e) {
            logger.error("Could not load associations", e);
            return Response.serverError().entity(e).build();
        }
        // TODO chiave multipla
        String onePropertyName = m2mConfiguration.getActualOnePropertyName();
        PropertyAccessor onePropertyAccessor = relationTableAccessor.getProperty(onePropertyName);
        // TODO chiave multipla
        String manyPropertyName = m2mConfiguration.getManySelectionProvider().getActualSelectionProvider().getReferences().get(0).getActualFromColumn().getActualPropertyName();
        PropertyAccessor manyPropertyAccessor = relationTableAccessor.getProperty(manyPropertyName);
        PropertyAccessor[] manyKeyProperties = manyTableAccessor.getKeyProperties();
        // TODO handle manyKeyProperties.length > 1
        PropertyAccessor manyPkAccessor = manyTableAccessor.getProperty(manyKeyProperties[0].getName());
        for (String pkString : selectedPrimaryKeys) {
            Object pkObject = manyTableAccessor.getIdStrategy().getPrimaryKey(pkString.split("/"));
            Object pk = manyPkAccessor.get(pkObject);
            if (!isExistingAssociation(manyPropertyAccessor, pk)) {
                Object newRelation = saveNewRelation(pk, onePropertyAccessor, manyPropertyAccessor);
                existingAssociations.add(newRelation);
            }
        }
        Iterator it = existingAssociations.iterator();
        while (it.hasNext()) {
            Object o = it.next();
            // TODO handle manyKeyProperties.length > 1
            Object pkObject = manyPropertyAccessor.get(o);
            String pkString = OgnlUtils.convertValue(pkObject, String.class);
            if (!selectedPrimaryKeys.contains(pkString)) {
                deleteRelation(o);
                it.remove();
            }
        }
    }
    session.getTransaction().commit();
    return objectCreated();
}
Also used : PropertyAccessor(com.manydesigns.elements.reflection.PropertyAccessor) JSONObject(org.json.JSONObject) JSONArray(org.json.JSONArray) JSONObject(org.json.JSONObject) URISyntaxException(java.net.URISyntaxException) JSONException(org.json.JSONException) RequiresPermissions(com.manydesigns.portofino.security.RequiresPermissions)

Aggregations

PropertyAccessor (com.manydesigns.elements.reflection.PropertyAccessor)46 ClassAccessor (com.manydesigns.elements.reflection.ClassAccessor)13 JavaClassAccessor (com.manydesigns.elements.reflection.JavaClassAccessor)12 JSONObject (org.json.JSONObject)5 SelectionProvider (com.manydesigns.elements.options.SelectionProvider)4 Field (com.manydesigns.elements.fields.Field)3 SelectField (com.manydesigns.elements.fields.SelectField)3 OgnlTextFormat (com.manydesigns.elements.text.OgnlTextFormat)3 TableAccessor (com.manydesigns.portofino.reflection.TableAccessor)3 Session (org.hibernate.Session)3 FieldSet (com.manydesigns.elements.annotations.FieldSet)2 SelectionModel (com.manydesigns.elements.options.SelectionModel)2 QueryStringWithParameters (com.manydesigns.elements.text.QueryStringWithParameters)2 TableCriteria (com.manydesigns.portofino.persistence.TableCriteria)2 SelectionProviderReference (com.manydesigns.portofino.resourceactions.m2m.configuration.SelectionProviderReference)2 Serializable (java.io.Serializable)2 Annotation (java.lang.annotation.Annotation)2 BigDecimal (java.math.BigDecimal)2 URISyntaxException (java.net.URISyntaxException)2 HashMap (java.util.HashMap)2