diff --git a/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/FixedSearchContext.java b/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/FixedSearchContext.java index 03ed33145..50ba16693 100644 --- a/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/FixedSearchContext.java +++ b/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/FixedSearchContext.java @@ -32,9 +32,9 @@ import org.iplass.mtp.entity.query.OrderBy; import org.iplass.mtp.entity.query.PreparedQuery; import org.iplass.mtp.entity.query.SortSpec; -import org.iplass.mtp.entity.query.Where; import org.iplass.mtp.entity.query.SortSpec.NullOrderingSpec; import org.iplass.mtp.entity.query.SortSpec.SortType; +import org.iplass.mtp.entity.query.Where; import org.iplass.mtp.entity.query.condition.Condition; import org.iplass.mtp.entity.query.condition.expr.And; import org.iplass.mtp.impl.parser.ParseContext; @@ -87,42 +87,37 @@ public boolean checkParameter() { @Override public OrderBy getOrderBy() { - OrderBy orderBy = null; EntityFilterManager efm = ManagerLocator.getInstance().getManager(EntityFilterManager.class); EntityFilter entityFilter = efm.get(getDefName()); - EntityFilterItem item = null; String filterName = getFilterName(); - if (entityFilter != null && filterName != null && !filterName.isEmpty()) { - item = entityFilter.getItem(filterName); + // TODO: 【要確認】通常検索(SearchContextBase.getOrderBy())とロジックが違うが、意図的か? + SortSpec sortSpec = getSortSpec(); + + OrderBy orderBy = new OrderBy(); + if (sortSpec != null) { + //画面でソート指定された場合は、その項目を第1ソートキーに + orderBy.add(sortSpec); } - - if (item != null && StringUtil.isNotEmpty(item.getSort())) { - SyntaxService service = ServiceRegistry.getRegistry().getService(SyntaxService.class); - OrderBySyntax syntax = service.getSyntaxContext(QuerySyntaxRegister.QUERY_CONTEXT).getSyntax(OrderBySyntax.class); - - ParseContext context = new ParseContext("order by " + item.getSort()); - try { - orderBy = syntax.parse(context); - - //画面でソート指定された場合は、その項目を第1ソートキーに - SortSpec sortSpec = getSortSpec(); - if (sortSpec != null) { - orderBy.getSortSpecList().add(0, sortSpec); + + // 検索結果の順番を一意にするために、補助的なソートを追加する + if (entityFilter != null && filterName != null && !filterName.isEmpty()) { + EntityFilterItem item = entityFilter.getItem(filterName); + if (item != null && StringUtil.isNotEmpty(item.getSort())) { + SyntaxService service = ServiceRegistry.getRegistry().getService(SyntaxService.class); + OrderBySyntax syntax = service.getSyntaxContext(QuerySyntaxRegister.QUERY_CONTEXT).getSyntax(OrderBySyntax.class); + ParseContext context = new ParseContext("order by " + item.getSort()); + try { + syntax.parse(context).getSortSpecList().forEach(orderBy::add); + return orderBy; + } catch (ParseException e) { + throw new SystemException(e.getMessage(), e); } - - } catch (ParseException e) { - throw new SystemException(e.getMessage(), e); - } - } else { - //画面でソート指定された場合は、その項目を第1ソートキーに - SortSpec sortSpec = getSortSpec(); - if (sortSpec != null) { - orderBy = new OrderBy(); - orderBy.add(sortSpec); } } - - return orderBy; + + //TODO: hasSortSetting()(= SearchLayout設定内のソート条件) を使うべき? or 今クラスは固定検索のため、SearchLayoutのソート条件は無視でよい?(現実装 = 後者) + //TODO: addする際に重複チェックするべきか? + return orderBy.add(Entity.OID, SortType.ASC); } /** diff --git a/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchContextBase.java b/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchContextBase.java index 1c1fd1311..0c6f502c7 100644 --- a/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchContextBase.java +++ b/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchContextBase.java @@ -221,10 +221,16 @@ public From getFrom() { @Override public OrderBy getOrderBy() { - OrderBy orderBy = null; // ソート設定が存在する場合 + // TODO: 以下、分かりづらくないか + // 画面でユーザーが指定したソート列: + // * hasSortSetting() には入ってないが + // * getSortSetting() には入っている + + // TODO: やりたいことは結局:OrderBy = (画面ソート列) + (ソート設定 or OID) + // ∴ 「まず前者を冒頭で処理した後に、後者を場合分けする」方が自然で分かりやすいのでは?(現状は、後者の場合分けから始まっているが) if (hasSortSetting()) { - orderBy = new OrderBy(); + OrderBy orderBy = new OrderBy(); for (SortSetting ss : getSortSetting()) { String sortKey = ss.getSortKey(); PropertyDefinition pd = getPropertyDefinition(sortKey); @@ -255,51 +261,53 @@ public OrderBy getOrderBy() { NullOrderingSpec nullOrderingSpec = getNullOrderingSpec(ss.getNullOrderType()); orderBy.add(sortKey, type, nullOrderingSpec); } - } else { - // ソート設定がない場合 - String sortKey = getSortKey(); - if (sortKey != null) { - if (Entity.OID.equals(sortKey)) { - orderBy = new OrderBy(); - orderBy.add(sortKey, getSortType()); + return orderBy; + } + // ソート設定がない場合 + String sortKey = getSortKey(); + if (sortKey == null) { + return null; + } + + if (Entity.OID.equals(sortKey)) { + return new OrderBy().add(sortKey, getSortType()); + } + PropertyColumn property = getLayoutPropertyColumn(sortKey); + // OID以外はSearchResultに定義されているPropertyのみ許可 + if (property == null) { + return null; + } + PropertyDefinition pd = getPropertyDefinition(sortKey); + // 参照プロパティの場合、画面上の表示項目でソート + // TODO: 上のロジックのコピペ。解消できないか + if (pd instanceof ReferenceProperty) { + if (property.getPropertyName().equals(sortKey)) { + // ソートキーが直接D&Dされた列の場合 + sortKey = sortKey + "." + getReferencePropertyDisplayName(property.getEditor()); + } else { + // ネストの存在チェック + NestProperty np = getLayoutNestProperty(property, sortKey); + if (np != null) { + sortKey = sortKey + "." + getReferencePropertyDisplayName(np.getEditor()); } else { - PropertyColumn property = getLayoutPropertyColumn(sortKey); - // OID以外はSearchResultに定義されているPropertyのみ許可 - if (property != null) { - PropertyDefinition pd = getPropertyDefinition(sortKey); - // 参照プロパティの場合、画面上の表示項目でソート - if (pd instanceof ReferenceProperty) { - if (property.getPropertyName().equals(sortKey)) { - // ソートキーが直接D&Dされた列の場合 - sortKey = sortKey + "." + getReferencePropertyDisplayName(property.getEditor()); - } else { - // ネストの存在チェック - NestProperty np = getLayoutNestProperty(property, sortKey); - if (np != null) { - sortKey = sortKey + "." + getReferencePropertyDisplayName(np.getEditor()); - } else { - // 未設定の項目 - sortKey = Entity.OID; - } - } - } else { - if (!property.getPropertyName().equals(sortKey)) { - // ソートキーが直接D&Dされた列以外の場合、ネストの存在チェック - NestProperty np = getLayoutNestProperty(property, sortKey); - if (np == null) { - // 未設定の項目 - sortKey = Entity.OID; - } - } - } - NullOrderingSpec nullOrderingSpec = getNullOrderingSpec(property.getNullOrderType()); - orderBy = new OrderBy(); - orderBy.add(sortKey, getSortType(), nullOrderingSpec); - } + // 未設定の項目 + sortKey = Entity.OID; + } + } + } else { + if (!property.getPropertyName().equals(sortKey)) { + // TODO: この分岐は上にはない。意図的か? + // ソートキーが直接D&Dされた列以外の場合、ネストの存在チェック + NestProperty np = getLayoutNestProperty(property, sortKey); + if (np == null) { + // 未設定の項目 + sortKey = Entity.OID; } } } - return orderBy; + NullOrderingSpec nullOrderingSpec = getNullOrderingSpec(property.getNullOrderType()); + // ソート順序を一意にするため、OIDをソートキーの末尾に追加 + return new OrderBy().add(sortKey, getSortType(), nullOrderingSpec).add(Entity.OID, SortType.ASC); } @Override diff --git a/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchListContext.java b/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchListContext.java index d326a3774..b30dccf3c 100644 --- a/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchListContext.java +++ b/iplass-gem/src/main/java/org/iplass/gem/command/generic/search/SearchListContext.java @@ -31,7 +31,6 @@ import org.iplass.mtp.entity.query.OrderBy; import org.iplass.mtp.entity.query.PreparedQuery; import org.iplass.mtp.entity.query.SortSpec; -import org.iplass.mtp.entity.query.SortSpec.NullOrderingSpec; import org.iplass.mtp.entity.query.SortSpec.SortType; import org.iplass.mtp.entity.query.Where; import org.iplass.mtp.entity.query.condition.Condition; @@ -100,47 +99,42 @@ public OrderBy getOrderBy() { OrderBy orderBy = null; if (StringUtil.isNotBlank(sortKey)) { + // TODO: 【要確認】通常検索(SearchContextBase.getOrderBy())とロジックが違うが、意図的か? PropertyDefinition pd = EntityViewUtil.getPropertyDefinition(sortKey, getEntityDefinition()); - String propName = sortKey; - if (pd instanceof ReferenceProperty) { - propName = sortKey + "." + Entity.OID; - } - if (StringUtil.isBlank(sortType)) { - orderBy = new OrderBy().add(new SortSpec(propName, SortType.DESC)); - } else { - orderBy = new OrderBy().add(new SortSpec(propName, SortType.valueOf(sortType))); - } - } else if (filter != null && StringUtil.isNotBlank(filter.getSort())) { + String propName = pd instanceof ReferenceProperty ? sortKey + "." + Entity.OID : sortKey ; + orderBy = new OrderBy().add(new SortSpec(propName, StringUtil.isBlank(sortType) ? SortType.DESC : SortType.valueOf(sortType))); + } + //TODO: addする際に重複チェックするべきか? + if (filter != null && StringUtil.isNotBlank(filter.getSort())) { SyntaxService service = ServiceRegistry.getRegistry().getService(SyntaxService.class); OrderBySyntax syntax = service.getSyntaxContext(QuerySyntaxRegister.QUERY_CONTEXT).getSyntax(OrderBySyntax.class); ParseContext context = new ParseContext("order by " + filter.getSort()); + if (orderBy == null) { + orderBy = new OrderBy(); + } try { - orderBy = syntax.parse(context); + syntax.parse(context).getSortSpecList().forEach(orderBy::add); + return orderBy; } catch (ParseException e) { throw new SystemException(e.getMessage(), e); } - } else if (hasSortSetting()) { - List setting = getSortSetting(); - for (SortSetting ss : setting) { - if (ss.getSortKey() != null) { - String key = null; - PropertyDefinition pd = getPropertyDefinition(ss.getSortKey()); - if (pd instanceof ReferenceProperty) { - key = ss.getSortKey() + "." + Entity.OID; - } else { - key = ss.getSortKey(); - } - SortType type = SortType.valueOf(ss.getSortType().name()); - NullOrderingSpec nullOrderingSpec = getNullOrderingSpec(ss.getNullOrderType()); - if (orderBy == null) orderBy = new OrderBy(); - orderBy.add(key, type, nullOrderingSpec); - } - } - } else { - orderBy = new OrderBy().add(new SortSpec(Entity.UPDATE_DATE, SortType.DESC)); } - - return orderBy; + if (hasSortSetting()) { + // TODO: 【要確認】通常検索(SearchContextBase.getOrderBy())とロジックが違うが、意図的か? + for (SortSetting ss : getSortSetting()) { + String _sortKey = ss.getSortKey(); + if (_sortKey == null) + continue; + + PropertyDefinition pd = getPropertyDefinition(_sortKey); + String key = pd instanceof ReferenceProperty ? _sortKey + "." + Entity.OID : _sortKey; + if (orderBy == null) + orderBy = new OrderBy(); + orderBy.add(key, SortType.valueOf(ss.getSortType().name()), getNullOrderingSpec(ss.getNullOrderType())); + } + return orderBy; + } + return (orderBy == null ? new OrderBy() : orderBy).add(new SortSpec(Entity.UPDATE_DATE, SortType.DESC)); } @Override diff --git a/iplass-gem/src/main/java/org/iplass/mtp/view/generic/element/section/SearchConditionSection.java b/iplass-gem/src/main/java/org/iplass/mtp/view/generic/element/section/SearchConditionSection.java index b58f1b06d..6d1de313d 100644 --- a/iplass-gem/src/main/java/org/iplass/mtp/view/generic/element/section/SearchConditionSection.java +++ b/iplass-gem/src/main/java/org/iplass/mtp/view/generic/element/section/SearchConditionSection.java @@ -101,7 +101,7 @@ public enum CsvUploadTransactionType { /** 詳細条件の表示件数 */ @MetaFieldInfo( displayName="詳細条件の表示件数", - displayNameKey="generic_element_section_SearchConditionSection_conditionDispCountDisplayNameKey", + displayNameKey="generic_element_section_SearchConditionSection_conditionDispCountDisplayNameKey", //TODO: locale_ja.jsにキー追加 inputType=InputType.NUMBER, rangeCheck=true, minRange=1,