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);
}
}
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;
}
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);
}
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;
}
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();
}
Aggregations