switcher, работающий в hGrid Видимо, это особенность совместимости switcher и hGrid. Решение:
1. Не изменяя SQL во VO, создать транзиторный атрибут с названием, например, swTran (Type: String, Updatable: Always);
2. В модуле VORowImpl изменить функцию-геттер так, чтобы она возвращала значение нашего параметра в зависимости от атрибута myCond:
public String getSwTran() {
Number i = getmyCond();
String cf = "";
if (i.intValue() == 0){
return cond1;
}else{
return cond2;
}
}
hGrid не перерисовывется при фильтрации данных Решение: перенести всю логику обертывания VO в условия в processRequest. И, как рекомендуется в гайде, после вызова одноименного метода родительского класса, прописать
OAHGridBean hGrid = (OAHGridBean)
webBean.findIndexedChildRecursive("Grid");
if (hGrid != null) {
hGrid.prepareForRendering(pageContext);
hGrid.setAutoQuery(false);
}
использование атрибутов из VO разных уровней в атрибутах бина (например, построение Destination URI) Необходимо соблюдение трех условий: 1) используемые атрибуты присутствуют во ВСЕХ уровнях, там, где они не имеют физического смысла, делаем Transient; 2) алиасы параметров должны быть идентичны с учетом регистра; 3) в атрибутах бина View Instance и View Attribute должен быть прописан любой уровень и параметр, имеющий физический смысл.
рекурсивное создание уровней hGrid Если сущность завязана сама на себя по id = parent_id, то может потребоваться автоматическое достраивание уровней hGrid. Решение:
1. Создаем VL с отношением id = parent_id c отношением 0..1 to *;
2. Добавляем второй экземпляр VO нижнего уровня в AM через связь с созданным VL
3. Достраиваем в PG дерево hGrid:
Здесь CommentLevel - ветка нижнего уровня с View Instance = Comment3VO1, ChildCommentLevel - создаваемая рекурсивно ветка с View Instance = Comment3VO2, CommentsLevel - узел с View Link Instance = CommentRecursiveVL1. Особое внимание - на узел RecursiveLink, в котором View Link Instance = CommentRecursiveVL1. Для него необходимо также задать параметр Ancestor Node = /oracle/apps/.../путь к пакету/<имя_страницы>.<имя_узла> - это необходимо для зацикливания при построении новых уровней. В нашем случае <имя_узла> = CommentsLevel.
безусловный переход на страницу pageContext.forwardImmediately(
"OA.jsp?page=/oracle/apps/xxx/xxx1/webui/MyPG",
null,
OAWebBeanConstants.KEEP_MENU_CONTEXT,
null,
null,
true, // retain AM
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
перерисовка страницы с hashmap HashMap params = new HashMap(10);
params.put("wPrm1", pageContext.getParameter("prm1"));
params.put("wPrm2", pageContext.getParameter("prm2"));
params.put("wPrm3", pageContext.getParameter("prm3"));
pageContext.forwardImmediatelyToCurrentPage(
params,
false,
OAWebBeanConstants.ADD_BREAD_CRUMB_NO);
...
public void processRequest{
...
(OAPageContext pageContext, OAWebBean webBean)
pageContext.getParameter("wPrm1"));
...
}
обработка исключения try{
OAApplicationModule am = pageContext.getApplicationModule(webBean);
OADBTransaction tran = (OADBTransaction)am.getTransaction();
prm = tran.getMyPRM();
}
catch (SQLException e) {
throw OAException.wrapperException(e);
}
invokeMethod с полными параметрами OAApplicationModule am = pageContext.getApplicationModule(webBean);
Serializable[] prm_values = {myNum, myStr};
Class[] prm_classes = {Number.class, String.class};
am.invokeMethod("MyProc", prm_values, prm_classes);
оборачивание VO в ограничения public void initQuery(Number Id, String Str) {
setWhereClause(null);
setWhereClauseParams(null);
setWhereClause("ent_id = :1 and ent_name = :2");
setWhereClauseParam(0, Id);
setWhereClauseParam(1, Str);
executeQuery();
}
программное изменение заголовка у webbean String someTitle = "title1";
((OAPageLayoutBean)webBean).setTitle(someTitle);
вызов DB процедуры OADBTransaction tran = getOADBTransaction();
OracleCallableStatement cStmt = null;
StringBuffer callSt = new StringBuffer();
callSt.append("begin XXX_PKG.set_params(");
callSt.append("pv_name => :1, ");
callSt.append("pv_id => :2, ");
callSt.append("pv_date => :3)");
callSt.append("; end;");
try {
cStmt = (OracleCallableStatement)
tran.createCallableStatement(callSt.toString(),
tran.DEFAULT);
cStmt.setString(1, prmUser);
cStmt.setNUMBER(2, prmID);
cStmt.setString(3, prmDate);
cStmt.execute();
cStmt.close();
}
catch (SQLException sqle) {
throw OAException.wrapperException(sqle);
}
содержимое колонки по центру (hGrid) private void getColCentered(OAPageContext pageContext,
OAWebBean webBean, OAHGridBean hGrid)
DataObjectList columnFormats = hGrid.getColumnFormats();
DictionaryData columnFormat = null;
int childIndex[] =
new int[] { pageContext.findChildIndex(hGrid, "Column1"),
pageContext.findChildIndex(hGrid, "Column2"),
pageContext.findChildIndex(hGrid, "Column3"),
};
for (int i: childIndex) {
columnFormat = (DictionaryData)columnFormats.getItem(i);
columnFormat.put(COLUMN_DATA_FORMAT_KEY, ICON_BUTTON_FORMAT);
}
}
динамическое создание View Object StringBuffer strBuf = new StringBuffer();
strBuf.append("select p from (select 0 p from dual ");
strBuf.append("union ");
strBuf.append("select 1 from dual)");
ViewObject myVO = am.createViewObjectFromQueryStmt("myVO", strBuf.toString());
myVO.setWhereClause("p = :1");
myVO.setWhereClauseParam(0, "0");
myVO.executeQuery();
myVO.first();
OAMessageChoiceBean mcBean = (OAMessageChoiceBean)webBean.findChildRecursive("Test");
mcBean.setValue(pageContext, (String)myVO.getCurrentRow().getAttribute(0));
myVO.remove();
конвертирование строки в объект oracle.jbo.domain.Date import java.text.SimpleDateFormat;
import java.text.DateFormat;
import oracle.cabo.ui.data.DataObjectList;
import oracle.cabo.ui.data.DictionaryData;
public void dateTest(){
String dateStr = "11.01.2013";
DateFormat df;
df = new SimpleDateFormat("dd.MM.yyyy");
java.util.Date tmp = null;
tmp = df.parse(dateStr);
oracle.jbo.domain.Date resDate = new oracle.jbo.domain.Date(new java.sql.Date(tmp.getTime()));
}
очистка датасета VO (итератор) public void clearVO(){
MyVOImpl MyVO = getMyVO1();
int rowCount = MyVO.getRowCount();
RowSetIterator deleteIter = MyVO.createRowSetIterator("deleteIter");
if (rowCount > 0) {
deleteIter.setRangeStart(0);
deleteIter.setRangeSize(rowCount);
for (int i = rowCount - 1; i > -1; i--) {
MyVORowImpl row = (MyVORowImpl)deleteIter.getRowAtRangeIndex(i);
row.remove();
}
}
deleteIter.closeRowSetIterator();
}
очистка датасета VO (метод) singleVO.executeEmptyRowSet();
поиск записи в VO CausesVOImpl causeVO = getCausesVO1();
if (!causeVO.isPreparedForExecution()){
causeVO.setMaxFetchSize(0);
}
causeVO.executeQuery();
causeVO.setRangeStart(0);
causeVO.setRangeSize(causeVO.getRowCount());
Number causeId = new Number(1);
OADBTransaction transaction = getOADBTransaction();
Key keyCauseId = new Key(new Object[] {causeId});
// 1 - макс. количество возвращаемых записей
Row causes[] = causeVO.findByKey(keyCauseId, 1);
if (causes != null && causes.length > 0) {
CausesVORowImpl causeRowVO = (CausesVORowImpl)causes[0];
...
}
построение мастер-детали в компоненте table 1) добавляем атрибут Expand типа String во VO-родитель и в запросе устанавливаем его константой 'N'. Детализация будет отображена только для строк, где (Expand is not null). N - по умолчанию деталь свернута, Y - развернута;
2) создаем View Link (MyVL), которым будут связаны данные, добавляем его и связь с дочерней таблицей в Application Module;
3) родительская таблица: параметр Detail View Attribute = Expand;
4) создаем бин детализации: правый клик по бину родительской таблицы - New - detail. В иерархии table components - detail создаем table layout, в нем создаем table. Можно и без первого, но он может потребоваться для добавления управляющих элементов в деталь;
5) дочерняя таблица: параметр Detail View Attribute = <имя атрибута, через который связывается родительская таблица>, View Link Instance = <имя экземпляра VL из Application Module>
Альтернативный метод связывания мастера и детали программно:
public void setMasterDetailLink(OAPageContext pageContext, OAWebBean webBean) {
OATableBean masterTable = (OATableBean)webBean.findChildRecursive("MasterTable");
if (masterTable != null) {
masterTable.setAttributeValue(CHILD_VIEW_ATTRIBUTE_NAME, "DetailId");
masterTable.setAttributeValue(VIEW_LINK_NAME, "MyVL1");
masterTable.setAllDetailsEnabled(true);
}
OATableBean detailTable = (OATableBean)webBean.findChildRecursive("DetailTable");
if (detailTable != null) {
detailTable.setAttributeValue(CHILD_VIEW_ATTRIBUTE_NAME, "MasterId");
detailTable.setAttributeValue(VIEW_LINK_NAME, "MyVL1");
detailTable.clearCache(pageContext);
}
}
форматирование с помощью интерфейса Formatter private void setColumnsFormat(OAPageContext pageContext, OAWebBean webBean, OAHGridBean hGrid){
int i;
String format = "#,##0;-#,##0";
ArrayList<OAMessageStyledTextBean> columns = new ArrayList<OAMessageStyledTextBean>();
Formatter formatter = new OADecimalValidater(format, format);
String columnNames[] = new String[] {"Col1", "Col2", "Col3"};
for (String str: columnNames){
OAMessageStyledTextBean col = (OAMessageStyledTextBean)
webBean.findChildRecursive(str);
if (col != null) columns.add(col);
}
for (i = 0; i<columns.size(); i++){
OAMessageStyledTextBean col = columns.get(i);
col.setAttributeValue(ON_SUBMIT_VALIDATER_ATTR, formatter);
}
}
очистка VO при использовании retainAM=Y Часто возникает проблема: при использовании retainAM (сохранение состояния модуля приложения) мастер-деталь в табличных бинах не отражает текущего состояния данных. Для очищения датасетов во всех VO, связанных с AM, имеет смысл использовать метод
am.clearVOCaches(null,Boolean.TRUE);
содержимое колонки по центру (table) private void alignCenter(OAPageContext pageContext, OAWebBean webBean) {
OATableBean versionTable = (OATableBean)webBean.findChildRecursive("SearchVO1");
versionTable.prepareForRendering(pageContext);
DataObjectList columnFormats = (DataObjectList)versionTable.getColumnFormats();
DictionaryData columnFormat = null;
//
int childIndex = pageContext.findChildIndex(versionTable, "imgEdit");
columnFormat = (DictionaryData)columnFormats.getItem(childIndex);
columnFormat.put(COLUMN_DATA_FORMAT_KEY, ICON_BUTTON_FORMAT);
//
childIndex = pageContext.findChildIndex(versionTable, "imgRemove");
columnFormat = (DictionaryData)columnFormats.getItem(childIndex);
columnFormat.put(COLUMN_DATA_FORMAT_KEY, ICON_BUTTON_FORMAT);
}