Wednesday, November 30, 2011

ADF Mobile

I am starting to play around with ADFs mobile stuff and forgot how to create the project. (Custom project then select the ADF Mobile Browser project feature). I have worked with trinidad before so the dev is not so tricky and drag and drop works so good times.


Note to self follow this link if you forget:
http://www.oracle.com/technetwork/developer-tools/jdev/ccset52-all-094777.html

Also I am using the droid emulator that comes with the SDK for testing will get an iPhone one at a later stage.

Tuesday, November 29, 2011

ADF refactoring hassles

Did a bit of refactoring and came accross a bit of a problem.

One of the directories all the VO's displayed as blank with no details (jdev popup errors everywhere) ... problems.

Solution
Stop Jdev.
Edit the Model.jpx file and add the directory missing manually to the file like such:
   <Containee
      Name="lov"
      PackageName="za.co.company.adf.test.model.lov"
      ObjectType="JboPackage">
      <DesignTime>
         <Attr Name="_VO" Value="true"/>
      </DesignTime>
   </Containee>
Start Jdev

Monday, November 28, 2011

ADF: Auto Suggest - solutions

I had implemented autosuggest on an input text field and it was all working so I moved it into our template to make it available application wide. The component stopped working (bind problem first then it would not return the value I needed into the text box). Here are the fixes.

The component is quick go button functionality with a suggest lookup to any menu link.

Bind problems solution: I needed to lookup the template binding using the current bind did not have my VO:
 BindingContext bctx = BindingContext.getCurrent();
  DCBindingContainer bindings = 
      bctx.findBindingContainer(
      "package_formTemplatePageDef");


Not returning the value solution: I had a uppercase conveter on my input text field - this was messing with my return value on the autosuggest. I removed it and it worked like magic.

The working code (note the query is limited to 5 rows in the VO with a bind variable linked to rownum):

JSFF
<af:panelGroupLayout id="pt_ag12" layout="horizontal">
  <af:inputText labelStyle="color: white" label="Go Link" id="pt_it7" value="#{menuBean.goValue}">
    <af:autoSuggestBehavior suggestItems="#{menuBean.suggestGoItems}"
      maxSuggestedItems="#{menuBean.maxSuggestionResults}"/>
  </af:inputText>
  <af:commandButton text="go" id="pt_cbGo" disabled="#{menuBean.goEnabled}"
    action="#{menuBean.performGo}"/>
</af:panelGroupLayout>

Bean
public int getMaxSuggestionResults() {
  return 5;
}

public List suggestGoItems(
  FacesContext fctx, oracle.adf.view.rich.model.AutoSuggestUIHints hints) {
  ArrayList selectItems = new ArrayList();
  String submittedValue = hints.getSubmittedValue();
  if(submittedValue != null && submittedValue.length() > 3) {
    BindingContext bctx = BindingContext.getCurrent();
    DCBindingContainer bindings = 
      bctx.findBindingContainer(
      "package_formTemplatePageDef");
    DCIteratorBinding binding = bindings.findIteratorBinding("AutoSuggestMenuVOIterator");

    HashMap variables = new HashMap();
    variables.put("userCode", super.getUserCode());
    variables.put("maxLimit", new Integer(getMaxSuggestionResults()));
    variables.put("searchName", submittedValue.toUpperCase());
    ADFUtils.setBindVariables(binding.getViewObject(), variables);
    binding.executeQuery();
    Row[] rows = binding.getAllRowsInRange();
    for(Row row : rows) {
      Object action = row.getAttribute("Action");
      String name = (String) row.getAttribute("Name");
      selectItems.add(new SelectItem(action, name));
    }
  }
  return selectItems;
}

public boolean isGoEnabled() {
  return goValue != null && goValue.length() > 3;
}

public String getGoValue() {
 return goValue;
}

public void setGoValue(String goValue) {
  this.goValue = goValue;
 }

public String performGo() {
  ExternalContext eCtx = JSFUtils.getExternalContext();
  //sql query to get the destination
  String destination = MenuUtility.getDestinationBasedOnKey(goValue, "name");

  if(destination != null) {
    String contextPath = ((HttpServletRequest) eCtx.getRequest()).getContextPath();
    try {
      logger.debug("redirectUrl=[" + contextPath + destination + "]");
      eCtx.redirect(contextPath + destination);
    } catch(Exception e) {
      logger.error("", e);
    }
  }
  return null;
}

ADFUtils.setBindVariables


public static void setBindVariables(ViewObject view, Map variables) {
  VariableValueManager vm = view.ensureVariableManager();
  for(String key : variables.keySet()) {
    vm.setVariableValue(key, variables.get(key));
  }
}

So anyway here are a couple of auto suggestions for the autosuggest component:

1) I want to control the value selected so a on select method would be nice.
2) The no results found text should be easily customized.

Wednesday, November 23, 2011

SVN: Subversion apache configuration smackdown

All I wanted out of life was to authenticate off Active Directory, have everyone with a valid user be able to read my svn repo and have a build user defined in a file for my Continuos integration (Non active directory user) and have a couple of AD users have read/write permissions sounds simple but maybe not so much.

This is my config file (in /etc/httpd/conf.d):
<AuthnProviderAlias ldap adf-ldap-alias>
#ldap config make sure the DN config is correct and the server is right
  AuthLDAPURL "ldap://adserver.co.za:3268/OU=User Accounts,DC=company,DC=co,DC=za?sAMAccountName?sub?(objectClass=*)" NONE
  AuthLDAPBindDN "svnuser@company.co.za"
  AuthLDAPBindPassword supersecret
</AuthnProviderAlias>

<AuthnProviderAlias file adf-file-alias>
#setup this file using  htpasswd
  AuthUserFile /etc/subversion/adf-auth-file
</AuthnProviderAlias>

<Location /adfrepo>
  DAV svn
  AuthType Basic
  AuthName "ADF Subversion Repository"
#this is where the magic happens for using two providers
  AuthBasicProvider adf-ldap-alias adf-file-alias
#Permissions that dont use AD Groups
  AuthzSVNAccessFile /etc/subversion/adf-authz
#path to your new repo
  SVNPath /usr/local/svn/adf
  Require valid-user
</Location>

Example of /etc/subversion/adf-authz (* = r means everybody has read access)

[groups]
svnAdf = usr1, usr2, bob

[:/]
@svnAdf = rw

[/]
* = r
@svnAdf = rw


Some nifty commands
#add a build user to the auth file
htpasswd -cmd /etc/subversion/adf-auth-file builduser

#copy old repo to new repo
svnsync init http://newsvn.company.co.za/adf http://oldsvn.company.co.za/svn/adf
svnsync sync file:///usr/local/svn/adf
svnadmin setuuid /usr/local/svn/adf
 

#create the new repo with correct permissions
svnadmin create /usr/local/svn/adf
chcon -R -t httpd_sys_content_rw_t /usr/local/svn/adf
chown -R svnadmin /usr/local/svn/adf
chgrp -R apache /usr/local/svn/adf
chmod -R g+w /usr/local/svn/adf

pre commit hook to enforce comments
$SVNLOOK log -t "$TXN" "$REPOS" | grep "[a-zA-Z0-9]" > /dev/null || { echo "Please enter a comment before you commit." >& 2; exit 1; }

Monday, November 21, 2011

SVN project creation - for my use only

My way add a project (already created) using a tortoise:

Repo browser add the folders to svn.
Checkout newly created folder tolocal disk where project is.
On explorer do a check for modifications add to your hearts content (remeber to uncheck unwanted dirs and add to ignore list).

Check in.


ADF : Row fetch limit application wide

JDeveloper 11.1.2.1

Found a nifty little setting in the adf-config.xml file Row Fetch Limit. This applies to all vo's in the application.


Click on the Application resources menu tab and select the adf-config file under ADF META-INF.
Click on the Business Components tab
Ner the bottom there is a Row Fetch Limit checkbox.



Why would I use this:

This setting can be used for performance reasons to set a resultset limit across the entire application.
This can prevent large meaningless user searches with million row results etc.

Friday, November 11, 2011

LOV problem in a multi line edit list

JDeveloper 11.1.2.1

We where having problems with our LOV lookups in a multi table edit list.

Where scolling down on the lov with a substantial number of records the LOV list would just reflect Fetching Records... indefinitely.

For now I have bound the multi list LOV to another lov model I had on the page with the same LOV in and it works but I will put some more time in finding another solution to this at some time because I am going on holiday next week - awesome.

Example
Had the following LOV on the page

<af:inputListOfValues id="ilov1" popupTitle="Search and Select: #{bindings.EmployeeId.hints.label}"
  value="#{bindings.EmployeeId.inputValue}"
  label="#{bindings.EmployeeId.hints.label}"
  model="#{bindings.EmployeeId.listOfValuesModel}"
  required="#{bindings.EmployeeId.hints.mandatory}"
  columns="#{bindings.EmployeeId.hints.displayWidth}"
  shortDesc="#{bindings.EmployeeId.hints.tooltip}">
  <f:validator binding="#{bindings.EmployeeId.validator}"/>
  <af:convertNumber groupingUsed="false" pattern="#{bindings.EmployeeId.format}"/>
</af:inputListOfValues>

And this LOV was the problematic on in an editable table.

<af:inputListOfValues id="employeeIdId"
 popupTitle="Search and Select: #{bindings.JobHistoryView1.hints.EmployeeId.label}"
 value="#{row.bindings.EmployeeId.inputValue}"
 model="#{row.bindings.EmployeeId.listOfValuesModel}"
 required="#{bindings.JobHistoryView1.hints.EmployeeId.mandatory}"
 columns="#{bindings.JobHistoryView1.hints.EmployeeId.displayWidth}"
 shortDesc="#{bindings.JobHistoryView1.hints.EmployeeId.tooltip}">
  <f:validator binding="#{row.bindings.EmployeeId.validator}"/>
  <af:convertNumber groupingUsed="false"
    pattern="#{bindings.JobHistoryView1.hints.EmployeeId.format}"/>
</af:inputListOfValues>

So I endeded up with this for the problematic one:
<af:inputListOfValues id="employeeIdId"
 popupTitle="Search and Select: #{bindings.JobHistoryView1.hints.EmployeeId.label}"
 value="#{row.bindings.EmployeeId.inputValue}"
 model="#{bindings.EmployeeId.listOfValuesModel}"
 required="#{bindings.JobHistoryView1.hints.EmployeeId.mandatory}"
 columns="#{bindings.JobHistoryView1.hints.EmployeeId.displayWidth}"
 shortDesc="#{bindings.JobHistoryView1.hints.EmployeeId.tooltip}">
  <f:validator binding="#{row.bindings.EmployeeId.validator}"/>
  <af:convertNumber groupingUsed="false"
    pattern="#{bindings.JobHistoryView1.hints.EmployeeId.format}"/>
</af:inputListOfValues>

Wednesday, November 9, 2011

ADF: Revert only changes to one View Object (mini rollback)

JDeveloper 11.1.2.1

I really struggled to get this working so hopefully this helps someone out:
I needed to just rollback the changes on a single vo backed popup and not the parent object so this is what I did. (not the pk for this view was rowid based and normal methods to do this just refused to work)
Also I failed to mention it is a multi line editable table.

NOTE: Performance was not an issue here.

Phase 1) Parent VO Impl
  We have a parent object for all our View Objects so I implemented this method there.

 public void clearAllCache() {
  //dont ask
  ViewRowSetImpl drsi = super.getDefaultRowSetInternal();
  while(drsi.hasNext()) {
    Row item = drsi.next();
  }

  Iterator iter = super.getEntityDef(0).getAllEntityInstancesIterator(this.getDBTransaction());
  while(iter.hasNext()) {
    EntityImpl entityItem = (EntityImpl) iter.next();
    if(entityItem.getEntityState() == EntityImpl.STATUS_NEW ||
      entityItem.getEntityState() == EntityImpl.STATUS_DELETED) {
      entityItem.refresh(EntityImpl.REFRESH_REMOVE_NEW_ROWS | 
  EntityImpl.REFRESH_UNDO_CHANGES);
    }
  }
  getViewObject().clearCache();
}

Phase 2) AM (implement this method and map it as a client interface)
 public void rollbackVO(String iteratorName) {
    DCIteratorBinding iterator = ((DCBindingContainer)   
      BindingContext.getCurrent().getCurrentBindingsEntry()).
      findIteratorBinding(iteratorName);

  ViewObject vo = iterator.getViewObject();
  if(vo instanceof WesbankVOImpl) {
    ((WesbankVOImpl) vo).clearAllCache();
  }
 }

Phase 3) Backing bean method (mapped to close popup button - all our popups work the same way and the backing bean holds the current popup iterator name)
public String resetPopup() {
  Map params = new HashMap();
  params.put("iteratorName", getCurrentPopupIteratorName());
  ADFUtils.executeOperationBindingWithoutException("rollbackVO", params);
  AdfFacesContext.getCurrentInstance().returnFromDialog(null, null);
  return null;

Phase 4) Page
Bind a method action to your page for the rollbackVO method

This still needs to be cleaned up (ie the getEntityDef(0) wont work everywhere).

Friday, November 4, 2011

Upgrade Jdeveloper jdk

It took me to long to look where you set this in the tools so this is what I did:

Stop Jdeveloper.
Did a search for my current JDK.
Changed the following files and replaced my old jdk location with my new one:

  [jdev install location]\Middleware\jdeveloper\jdev\bin\jdev.conf
  [WEBLOGIC install location]\DefaultDomain\bin\setDomainEnv.cmd (Usually defaults to your user directory)

Optional files to change: (if you are going to remove the old jdk and you want these to work)
  [jdev install location]\Middleware\jdeveloper\.product.properties
  [jdev install location]\Middleware\wlserver_10.3\.product.propertie
  [jdev install location]\Middleware\wlserver_10.3\common\bin\commEnv.cmd
  [jdev install location]\Middleware\utils\uninstall\uninstall.cmd
  [jdev install location]\Middleware\utils\quickstart\quickstart.cmd
  [jdev install location]\Middleware\utils\bsu\bsu.cmd