filtering data with d2w

19
Filtering data with D2W Philippe Rabier - twitter.com/prabier Sophiacom

Upload: wo-community

Post on 19-May-2015

259 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Filtering data with D2W

Filtering data with D2W Philippe Rabier - twitter.com/prabierSophiacom

Page 2: Filtering data with D2W

What is the problem to solve?

Page 3: Filtering data with D2W

Company

EOEntityA

EOEntityB

User

EOEntityC

Page 4: Filtering data with D2W

• Use D2W

• Limit the visibility of the data

• Use conventions to name relationships (for example, any toOne relationship to Company entity, is called company)

• Minimize the code

• Be magic!

The Requirements

Page 5: Filtering data with D2W

Feedback from You ’N Push

Page 6: Filtering data with D2W

First Solution

Working at the editingContext level

Page 7: Filtering data with D2W

modified fetchspec

notificationec factory ec

company

objectsWithFetchSpecification()

creates businessFP

fetchspec

Page 8: Filtering data with D2W

How the qualifier is modified?

public void alterFetchSpecification(final NSNotification aNotification) { EOEditingContext ec = (EOEditingContext) aNotification.object(); if (shouldAddRestrictionQualifier) { Company aCompany = (NOClient) ec.userInfoForKey(NBEditingContextFactory.COMPANY_KEY); final EOFetchSpecification fs = (EOFetchSpecification) aNotification.userInfo().valueForKey(COEditingContext.FETCH_SPEC_KEY); if (aCompany != null && fs != null) { EOEntity aEntity = EOUtilities.entityNamed(ec, fs.entityName());

EOQualifier fsQualifier = fs.qualifier(); if (fsQualifier != null) { NSSet<String> keys = fsQualifier.allQualifierKeys(); for (String aKey : keys) { if (aKey.contains("company")) { shouldAddRestrictionQualifier = false; break; } } } if (shouldAddRestrictionQualifier) { EOQualifier aRestrictionQualifier = clientRestrictionQualifier(aEntity, aClient); if (aRestrictionQualifier != null) { if (fsQualifier != null) fsQualifier = new EOAndQualifier(new NSArray<EOQualifier>(new EOQualifier[] {fsQualifier, aRestrictionQualifier})); else fsQualifier = aRestrictionQualifier; fs.setQualifier(fsQualifier); } } } } }

Page 9: Filtering data with D2W

How the qualifier is modified?

public EOQualifier companyRestrictionQualifier(final EOEntity entity, final Company company) {

EOQualifier aQualifier = null; if (entity.name().equals(Company.Keys.ENTITY_NAME)) aQualifier = new EOKeyValueQualifier(Company.Keys.NAME, EOQualifier.QualifierOperatorEqual, company.name()); else if (entity.relationshipNamed("company") != null) aQualifier = new EOKeyValueQualifier("company", EOQualifier.QualifierOperatorEqual, company); else if (entity.relationshipNamed("entityB") != null) aQualifier = new EOKeyValueQualifier("entityB.company", EOQualifier.QualifierOperatorEqual, client); else if (entity.relationshipNamed("entityC") != null) ...;

if (log.isDebugEnabled()) log.debug("method: qualifier: " + aQualifier); return aQualifier; }

Page 10: Filtering data with D2W

It works great

but there is a little problem

it’s too low level

Page 11: Filtering data with D2W

An Example of Problem

public void validateForSave() throws ValidationException { super.validateForSave(); ERXEOControlUtilities.validateUniquenessOf(this, NOUser.Keys.LOGIN); ERXEOControlUtilities.validateUniquenessOf(this, NOUser.Keys.EMAIL); }

public void validateForSave() throws ValidationException { super.validateForSave(); editingContext().setUserInfoForKey(Boolean.FALSE, NBEditingContextFactory.NO_RESTRICTION_QUAL_KEY); ERXEOControlUtilities.validateUniquenessOf(this, NOUser.Keys.LOGIN); ERXEOControlUtilities.validateUniquenessOf(this, NOUser.Keys.EMAIL); editingContext().setUserInfoForKey(Boolean.TRUE, NBEditingContextFactory.NO_RESTRICTION_QUAL_KEY); }

Page 12: Filtering data with D2W

Second Solution

Page 13: Filtering data with D2W

• Displaying a list

• Using a query component

• Using ERD2WEditToManyRelationship component

• Using ERD2WEditToOneRelationship component

When should we filter?

Page 14: Filtering data with D2W

• Modify the NavigationController object

• Change the data source

Displaying a list

public WOComponent listPageForEntityName(final String entityName) { ListPageInterface newListPageInterface = D2W.factory().listPageForEntityNamed(entityName, session()); EODatabaseDataSource dataSource = new EODatabaseDataSource(ERXEC.newEditingContext(), entityName); EOEntity entity = ERXEOAccessUtilities.entityNamed(null, entityName); EOQualifier auxQual = NBBusinessLogicPrincipal.getSharedInstance().clientRestrictionQualifier(entity, ((Session)session()).getCompany());

dataSource.setAuxiliaryQualifier(auxQual);

newListPageInterface.setDataSource(dataSource); return (WOComponent) newListPageInterface; }

Page 15: Filtering data with D2W

• Use a query delegate

• Override the method queryDataSource(ERD2WQueryPage sender)

Using a query component

{ author = 100; class = "com.webobjects.directtoweb.Rule"; lhs = { class = "com.webobjects.eocontrol.EOKeyValueQualifier"; key = pageConfiguration; selectorName = isEqualTo; value = QueryMyEntity; }; rhs = { class = "er.directtoweb.ERDDelayedObjectCreationAssignment"; keyPath = queryDataSourceDelegate; value = "ca.wowodc.very.util.pascal.delegate.SomeOneElse"; };}

Page 16: Filtering data with D2W

• Maybe subclass the 2 component is the best solution

• Use restrictingFetchSpecification key. If all fetchspec have the same name, it’s possible to build a generic rule.

• Need to be modified to add the possibility to set a binding to the fetchspec

• Maybe a lot of pain to create many fetchspec in the EOModel

EditRelationship components

Page 17: Filtering data with D2W

How the qualifier is modified?

public Object restrictedChoiceList() { String restrictedChoiceKey=(String)d2wContext().valueForKey("restrictedChoiceKey"); if( restrictedChoiceKey!=null && restrictedChoiceKey.length()>0 ) return valueForKeyPath(restrictedChoiceKey); String fetchSpecName=(String)d2wContext().valueForKey("restrictingFetchSpecification"); if(fetchSpecName != null) { EORelationship relationship = ERXUtilities.relationshipWithObjectAndKeyPath(object(), (String)d2wContext().valueForKey("propertyKey")); if(relationship != null) return EOUtilities.objectsWithFetchSpecificationAndBindings(object().editingContext(), relationship.destinationEntity().name(),fetchSpecName,null); } return null; }

Page 18: Filtering data with D2W

@prabier

Follow me!

Page 19: Filtering data with D2W

Q&ATBD