general questions

5 posts / 0 new
Last post
axidavid
Offline
Joined: 07/21/2010
general questions

hi i'm currently reviewing jspresso and it is very powerful

but i'd like to know if we can use it in a real project

1- how do jspresso handle big tables (with more than 10000 rows). paginated grid, virtual load in another thread ...

2-do you plan to integrate some calendar event component (ala outlook, there are some javascript libraries that have one)

3- do you plan to generate other gui client (like eclipse RCP)

4- how does jspresso handle view that are not directly backed by an entity

5- is it possible to call stored procedures to get some db computed result sets  ??

6- how does jspresso handle multi-page view ?

7- in a crm type app, i'd like , when a sale man log in, to filter the customer to show only the customers is attached to. is it possible ??

 

thanks in advance

 

david

atao
Offline
Joined: 10/15/2008
general questions: some answers

David,

3- do you plan to generate other gui client (like eclipse RCP)

and javaFX, and ..., and ... Wink

4- how does jspresso handle view that are not directly backed by an entity

You have to specify the modelDescriptor associated to the viewDescriptor.

Search on the forum about WizardAction and WizardStep.

7- [...] to filter the customer to show only the customers is attached to. is it possible ??

There is no such out of the box componant.

ATM I used the custom properties of UserPrincipal to do it.

I load from a LDAP the "domains" (the sale man's custumers, in the code below it's the branches) associated to the user (your sale man), but it can be done with any data base.

When the workspace is selected, then the list of "domains"  authorized is filtered using the above rights, see DomainQueryModuleFilterAction below.

HIH

Regards

Pierre

 

===============================================================

 
  <bean
    id="authorizedBranchQueryModuleFilterBackendAction"
    class="org.jspresso.framework.application.backend.action.module.QueryModuleFilterAction">
    <property name="queryAction" ref="queryEntitiesBackAction" />
    <property name="nextAction">
      <bean class="org.popsuite.framework.application.backend.action.module.DomainQueryModuleFilterAction">
        <property name="domainReferencesProvider">
          <bean class="org.popsuite.hr.backend.action.module.BranchDomainReferencesProvider" />
        </property>
      </bean>
    </property>
  </bean>

  <bean
    id="Payroll.workspace"
    parent="abstractWorkspace"
    scope="prototype">
    <property name="name"         value="payroll.workspace" />
    <property name="description"  value="payroll.workspace.description" />
    <property name="iconImageURL" value="classpath:org/popsuite/common/images/structure-48x48.png" />
    <property name="itemSelectionAction">
      <bean class="org.popsuite.framework.application.backend.action.module.DomainSelectionChangeAction">
        <property name="domainReferencesProvider">
          <bean class="org.popsuite.hr.backend.action.module.BranchDomainReferencesProvider" />
        </property>
      </bean>
    </property>
    <property name="modules">
      <list>
        <bean parent="abstractFilterableBeanCollectionModule">
          <property name="name"                       value="branches.module" />
          <property name="description"                value="branches.module.description" />
          <property name="iconImageURL"               value="classpath:org/popsuite/common/images/company-48x48.png" />
          <property name="elementComponentDescriptor" ref="Branch" />
          <property name="elementViewDescriptor"      ref="branch.module.view" />
          <property name="orderingProperties">
            <map>
              <entry key="name" value="ASCENDING" />
            </map>
          </property>
          <property name="startupAction">
            <bean parent="initModuleFilterAction">
              <property name="nextAction">
                <bean class="org.jspresso.framework.application.backend.action.module.QueryModuleFilterAction">
                  <property name="wrappedAction"
                            ref="authorizedBranchQueryModuleFilterBackendAction" />
                </bean>
              </property>
            </bean>
          </property>
          <property name="projectedViewDescriptor">
            <bean parent="filterableBeanCollectionModuleView">
              <property name="readOnly"      value="true" />
              <property name="selectionMode" value="SINGLE_SELECTION" />
            </bean>
          </property>
        </bean>
      </list>
    </property>
  </bean>

package org.popsuite.framework.application.backend.action.module;

import static org.popsuite.framework.security.auth.spi.PopsuiteLdapLoginModule.POSITIONS_CUSTOM_PROPERTY;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jspresso.framework.action.IActionHandler;
import org.jspresso.framework.application.backend.action.BackendAction;
import org.jspresso.framework.application.model.FilterableBeanCollectionModule;
import org.jspresso.framework.model.component.IComponent;

/**
 * Select the domains to be exposed for the current user.
 *
 * To be injected as nextAction of QueryModuleFilterAction
 *
 * If no candidatesProvider is injected, then no checking: module's object list stays unchanged
 *
 * @param <T>
 *            the actuel domain type used.
 */
public class DomainQueryModuleFilterAction<T extends IComponent>  
extends BackendAction
{
    
    private ComponentDomainReferencesProvider<T> candidatesProvider;

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean execute(IActionHandler actionHandler,
            Map<String, Object> context) {
        if(candidatesProvider != null) {
            filterModuleObjects(actionHandler, context);    
        }
        return super.execute(actionHandler, context);
    }

    private void filterModuleObjects(IActionHandler actionHandler,
            Map<String, Object> context) {
        Map<String, Set<String>> positions = getPositions(context);
        List<T> domains = getDomains(context);
        domains = selectDomainsAmongPositions(domains, positions);
        setSelectedDomainsInContext(domains, context);
    }
    
    private Map<String, Set<String>> getPositions(Map<String, Object> context) {
        @SuppressWarnings("unchecked")
        Map<String, Set<String>> positions = (Map<String, Set<String>>) getApplicationSession(context)
            .getPrincipal().getCustomProperty(POSITIONS_CUSTOM_PROPERTY);
        return positions;
    }

    private List<T> getDomains(Map<String, Object> context) {
        FilterableBeanCollectionModule module = (FilterableBeanCollectionModule) getModule(context);
        @SuppressWarnings("unchecked")
        List<T> domains = (List<T>) module.getModuleObjects();
        return domains;
    }

    private void setSelectedDomainsInContext(List<T> domains, Map<String, Object> context) {
        FilterableBeanCollectionModule module = (FilterableBeanCollectionModule) getModule(context);
        module.setModuleObjects(domains);
    }
    
    private List<T> selectDomainsAmongPositions(List<T> domains,
            Map<String, Set<String>> positions)
    {
        List<T> result = new ArrayList<T>(domains.size());
        for(T domain : domains) {
            if (isDomainAmongPositions(domain, positions)) {
                result.add(domain);                
            }
        }
        return result;
    }
    
    private boolean isDomainAmongPositions(T domain, Map<String, Set<String>> positions) {
        String[] candidates = candidatesProvider.getReferenceCandidatesForDomain(domain);
        if(candidates == null) return false;
       
        for(String candidate:candidates) {
            if(positions.containsKey(candidate)) return true;
        }
        return false;
    }
    
    public void setDomainReferencesProvider(ComponentDomainReferencesProvider<T> candidatesProvider) {
        this.candidatesProvider = candidatesProvider;
    }

}

maxime
Offline
Joined: 06/23/2008
Hi David Here is some answer

Hi David

Here is some answer to your questions…

  1. a) Querying on big tables : Jspresso's common module " filterModule " is managing pagination just by setting  the " pageSize=n " attribute in the Entity definition : this will activate a toolbar with " previous " and " next " page button.

    b) You have to take care on master detail relations : for example, let's think Customer have thousands of Invoices… you will avoid to display a master detail on that relation : in this case Jspresso will load all Customer's Invoices… But we're thinking that this is matter of design : you can for example separate this into two Jspresso modules : one for Customer (with only the last ten Invoices for example) and the second one for Invoices (using a filterModule and pagination).

  2. We do not plan to integrate calendar view at the time of writing this. One important thing is that Jspresso is open to integrate any custom component : for example for a specific project we develop a complex Flex component (with a gantt view, drag n drop, etc.) and we develop a Jspresso wrapper for this component. Now we can integrate this component anywhere and it acts like any other Jspresso component… If you develop a calendar component and It's wrapper, may be will you share it with the Jspresso community !
  3. We do not plan to generate other gui client at the time of writing this. What is the better gui for a you ? Is Flex or Qooxdoo suitable for you ?
  4. You can define a "Component" that is backed by a simple Java class. Component's acts like Entities for the gui representation.
  5. Yes it is possible. For example you can describe a service on one Entity (or Component) that will call you're stored procedure.
  6. If you mean text representation "wysywig" like Word, we do not have such component at this time.
  7. You can a achieve this using a fiterModule. You will have to develop a "QueryRefiner" to customize the hibernate query… then you will inject this component into the "queryModuleFilterAction" action…

Hope this will help

Regards,
Maxime

axidavid
Offline
Joined: 07/21/2010
1a : ok . i will try that 1b

1a : ok . i will try that

1b : good idea. how do you specify you only want the last 10 invoices ??

3- i spend some times on eclipse rcp. and i was just asking

6- no i mean, an entity with hundreds of properties , that needs several pages to display

 

thanks for your answers

 

david

maxime
Offline
Joined: 06/23/2008
6- May be Tabs ? Or a wizard

6- May be Tabs ? Or a wizard that will chain all pages ?