001/* 002 * Copyright 2011 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.odf.enumeration; 017 018import java.util.Collections; 019import java.util.HashMap; 020import java.util.HashSet; 021import java.util.LinkedHashMap; 022import java.util.List; 023import java.util.Map; 024import java.util.Set; 025import java.util.stream.Collectors; 026 027import org.apache.avalon.framework.component.Component; 028import org.apache.avalon.framework.service.ServiceException; 029import org.apache.avalon.framework.service.ServiceManager; 030import org.apache.avalon.framework.service.Serviceable; 031import org.apache.cocoon.xml.AttributesImpl; 032import org.apache.cocoon.xml.XMLUtils; 033import org.apache.commons.lang3.StringUtils; 034import org.xml.sax.ContentHandler; 035import org.xml.sax.SAXException; 036 037import org.ametys.cms.contenttype.ContentAttributeDefinition; 038import org.ametys.cms.contenttype.ContentType; 039import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 040import org.ametys.cms.contenttype.ContentTypesHelper; 041import org.ametys.cms.repository.Content; 042import org.ametys.cms.repository.ContentQueryHelper; 043import org.ametys.cms.repository.ContentTypeExpression; 044import org.ametys.core.ui.Callable; 045import org.ametys.plugins.repository.AmetysObjectIterable; 046import org.ametys.plugins.repository.AmetysObjectIterator; 047import org.ametys.plugins.repository.AmetysObjectResolver; 048import org.ametys.plugins.repository.UnknownAmetysObjectException; 049import org.ametys.plugins.repository.model.RepeaterDefinition; 050import org.ametys.plugins.repository.query.SortCriteria; 051import org.ametys.plugins.repository.query.expression.AndExpression; 052import org.ametys.plugins.repository.query.expression.Expression.Operator; 053import org.ametys.plugins.repository.query.expression.StringExpression; 054import org.ametys.runtime.config.Config; 055import org.ametys.runtime.model.ElementDefinition; 056import org.ametys.runtime.model.ModelItem; 057import org.ametys.runtime.model.ModelItemContainer; 058import org.ametys.runtime.model.View; 059import org.ametys.runtime.model.ViewElement; 060import org.ametys.runtime.model.ViewItem; 061import org.ametys.runtime.model.ViewItemContainer; 062import org.ametys.runtime.plugin.component.AbstractLogEnabled; 063 064/** 065 * This component handles ODF reference tables 066 * 067 */ 068public class OdfReferenceTableHelper extends AbstractLogEnabled implements Component, Serviceable 069{ 070 /** Avalon Role */ 071 public static final String ROLE = OdfReferenceTableHelper.class.getName(); 072 073 /** Abstract table ref */ 074 public static final String ABSTRACT_TABLE_REF = "odf-enumeration.AbstractTableRef"; 075 /** Domain */ 076 public static final String DOMAIN = "odf-enumeration.Domain"; 077 /** Degree */ 078 public static final String DEGREE = "odf-enumeration.Degree"; 079 /** Level */ 080 public static final String LEVEL = "odf-enumeration.Level"; 081 /** Program type. */ 082 public static final String PROGRAM_TYPE = "odf-enumeration.ProgramType"; 083 /** Form of teaching */ 084 public static final String FORMOFTEACHING_METHOD = "odf-enumeration.FormofteachingMethod"; 085 /** Orgnization of teaching */ 086 public static final String FORMOFTEACHING_ORG = "odf-enumeration.FormofteachingOrg"; 087 /** Teaching method */ 088 public static final String TEACHING_ACTIVITY = "odf-enumeration.TeachingActivity"; 089 /** Type of training course */ 090 public static final String INTERNSHIP = "odf-enumeration.Internship"; 091 /** Distance learning modalities */ 092 public static final String DISTANCE_LEARNING_MODALITIES = "odf-enumeration.DistanceLearningModalities"; 093 /** Place */ 094 public static final String PLACE = "odf-enumeration.Place"; 095 /** Teaching term. */ 096 public static final String TEACHING_TERM = "odf-enumeration.TeachingTerm"; 097 /** Time slot */ 098 public static final String TIME_SLOT = "odf-enumeration.TimeSlot"; 099 /** Code ROME */ 100 public static final String CODE_ROME = "odf-enumeration.CodeRome"; 101 /** Code ERASMUS */ 102 public static final String CODE_ERASMUS = "odf-enumeration.CodeErasmus"; 103 /** Code DGESIP */ 104 public static final String CODE_DGESIP = "odf-enumeration.CodeDgesip"; 105 /** Code SISE */ 106 public static final String CODE_SISE = "odf-enumeration.CodeSise"; 107 /** Code Cite97 */ 108 public static final String CODE_CITE97 = "odf-enumeration.CodeCite97"; 109 /** Code FAP */ 110 public static final String CODE_FAP = "odf-enumeration.CodeFap"; 111 /** Code NSF */ 112 public static final String CODE_NSF = "odf-enumeration.CodeNsf"; 113 /** RNCP level */ 114 public static final String RNCP_LEVEL = "odf-enumeration.RncpLevel"; 115 /** Join orgunit*/ 116 public static final String JOIN_ORGUNIT = "odf-enumeration.JoinOrgunit"; 117 /** Mention licence */ 118 public static final String ABSTRACT_MENTION = "odf-enumeration.Mention"; 119 /** Mention licence */ 120 public static final String MENTION_LICENCE = "odf-enumeration.MentionLicence"; 121 /** Mention licence pro */ 122 public static final String MENTION_LICENCEPRO = "odf-enumeration.MentionLicencepro"; 123 /** Mention master */ 124 public static final String MENTION_MASTER = "odf-enumeration.MentionMaster"; 125 /** Abstract table ref for category */ 126 public static final String ABSTRACT_TABLE_REF_CATEGORY = "odf-enumeration.AbstractTableRefCategory"; 127 /** Apprenticeship contract */ 128 public static final String APPRENTICESHIP_CONTRACT = "odf-enumeration.ApprenticeshipContract"; 129 /** Available certification */ 130 public static final String AVAILABLE_CERTIFICATION = "odf-enumeration.AvailableCertification"; 131 /** Campus */ 132 public static final String CAMPUS = "odf-enumeration.Campus"; 133 /** Category for code Erasmus */ 134 public static final String CODE_ERASMUS_CATEGORY = "odf-enumeration.CodeErasmusCategory"; 135 /** Category for code FAP */ 136 public static final String CODE_FAP_CATEGORY = "odf-enumeration.CodeFapCategory"; 137 /** Nature of container */ 138 public static final String CONTAINER_NATURE = "odf-enumeration.ContainerNature"; 139 /** Nature of course */ 140 public static final String COURSE_NATURE = "odf-enumeration.CourseNature"; 141 /** Discipline */ 142 public static final String DISCIPLINE = "odf-enumeration.Discipline"; 143 /** Duration */ 144 public static final String DURATION = "odf-enumeration.Duration"; 145 /** ECTS */ 146 public static final String ECTS = "odf-enumeration.Ects"; 147 /** Foreign place */ 148 public static final String FOREIGN_PLACE = "odf-enumeration.ForeignPlace"; 149 /** International education */ 150 public static final String INTERNATIONAL_EDUCATION = "odf-enumeration.InternationalEducation"; 151 /** Language */ 152 public static final String LANGUAGE = "odf-enumeration.Language"; 153 /** OrgUnit type */ 154 public static final String ORGUNIT_TYPE = "odf-enumeration.OrgUnitType"; 155 /** Period */ 156 public static final String PERIOD = "odf-enumeration.Period"; 157 /** Period type */ 158 public static final String PERIOD_TYPE = "odf-enumeration.PeriodType"; 159 /** Person role */ 160 public static final String PERSON_ROLE = "odf-enumeration.PersonRole"; 161 /** Program field */ 162 public static final String PROGRAM_FIELD = "odf-enumeration.ProgramField"; 163 /** Sectors */ 164 public static final String SECTORS = "odf-enumeration.Sectors"; 165 /** Nature of course part */ 166 public static final String ENSEIGNEMENT_NATURE = "odf-enumeration.EnseignementNature"; 167 /** Category of nature of course part */ 168 public static final String ENSEIGNEMENT_NATURE_CATEGORY = "odf-enumeration.EnseignementNatureCategory"; 169 /** Skill */ 170 public static final String SKILL = "odf-enumeration.Skill"; 171 /** Skill set */ 172 public static final String SKILL_SET = "odf-enumeration.SkillSet"; 173 /** Attribute name for mention type in table refe degree */ 174 public static final String DEGREE_MENTION_TYPE = "mentionType"; 175 176 private AmetysObjectResolver _resolver; 177 178 private ContentTypeExtensionPoint _cTypeEP; 179 180 private ContentTypesHelper _cTypeHelper; 181 182 @Override 183 public void service(ServiceManager manager) throws ServiceException 184 { 185 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 186 _cTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 187 _cTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 188 } 189 190 /** 191 * Determines if the content type is a ODF table reference 192 * @param cTypeId The id of content type 193 * @return true if the content type is a ODF table reference 194 */ 195 public boolean isTableReference(String cTypeId) 196 { 197 return _cTypeHelper.getAncestors(cTypeId).contains(ABSTRACT_TABLE_REF); 198 } 199 200 /** 201 * Determines if the content is an entry of a ODF table reference 202 * @param content The content 203 * @return <code>true</code> if the content is an entry of a ODF table reference 204 */ 205 public boolean isTableReferenceEntry(Content content) 206 { 207 String[] cTypeIds = content.getTypes(); 208 for (String cTypeId : cTypeIds) 209 { 210 if (isTableReference(cTypeId)) 211 { 212 return true; 213 } 214 } 215 return false; 216 } 217 218 /** 219 * Get the id of table references 220 * @return The content type's id 221 */ 222 public Set<String> getTableReferenceIds() 223 { 224 Set<String> tableRefIds = new HashSet<>(); 225 226 for (String cTypeId : _cTypeEP.getExtensionsIds()) 227 { 228 if (_cTypeHelper.getAncestors(cTypeId).contains(ABSTRACT_TABLE_REF)) 229 { 230 tableRefIds.add(cTypeId); 231 } 232 } 233 return tableRefIds; 234 } 235 236 /** 237 * Get the attribute definitions for table references for a given content type 238 * @param cTypeId The id of content type 239 * @return The attribute definitions for table references 240 */ 241 public Map<String, ContentAttributeDefinition> getTableRefAttributeDefinitions(String cTypeId) 242 { 243 ContentType cType = _cTypeEP.getExtension(cTypeId); 244 return _getTableRefAttributes(cType); 245 } 246 247 private Map<String, ContentAttributeDefinition> _getTableRefAttributes(ModelItemContainer modelItemContainer) 248 { 249 Map<String, ContentAttributeDefinition> tableRefAttributes = new LinkedHashMap<>(); 250 251 for (ModelItem modelItem : modelItemContainer.getModelItems()) 252 { 253 if (modelItem instanceof ContentAttributeDefinition) 254 { 255 ContentAttributeDefinition attributeDefinition = (ContentAttributeDefinition) modelItem; 256 if (isTableReference(attributeDefinition.getContentTypeId())) 257 { 258 tableRefAttributes.put(attributeDefinition.getPath(), attributeDefinition); 259 } 260 } 261 else if (modelItem instanceof ModelItemContainer && !(modelItem instanceof RepeaterDefinition)) 262 { 263 // enumerated attributes in repeaters are not supported 264 tableRefAttributes.putAll(_getTableRefAttributes((ModelItemContainer) modelItem)); 265 } 266 } 267 268 return tableRefAttributes; 269 } 270 271 /** 272 * Get the attribute definitions for table references for a given content type and a view 273 * @param cTypeId The id of content type 274 * @param viewName the name of the view. Cannot be null. 275 * @return The attributes definitions for table references 276 */ 277 public Map<String, ContentAttributeDefinition> getTableRefAttributeDefinitions(String cTypeId, String viewName) 278 { 279 ContentType cType = _cTypeEP.getExtension(cTypeId); 280 281 View view = cType.getView(viewName); 282 return _getTableRefAttributes(view); 283 } 284 285 private Map<String, ContentAttributeDefinition> _getTableRefAttributes(ViewItemContainer viewItemContainer) 286 { 287 Map<String, ContentAttributeDefinition> tableRefAttributes = new LinkedHashMap<>(); 288 289 for (ViewItem viewItem : viewItemContainer.getViewItems()) 290 { 291 if (viewItem instanceof ViewElement) 292 { 293 ElementDefinition definition = ((ViewElement) viewItem).getDefinition(); 294 if (definition instanceof ContentAttributeDefinition) 295 { 296 tableRefAttributes.put(definition.getPath(), (ContentAttributeDefinition) definition); 297 } 298 } 299 else if (viewItem instanceof ViewItemContainer) 300 { 301 tableRefAttributes.putAll(_getTableRefAttributes((ViewItemContainer) viewItem)); 302 } 303 } 304 305 return tableRefAttributes; 306 } 307 308 /** 309 * Get the content type for mention for this degree 310 * @param degreeIds The ids of degrees 311 * @return A map with the id of content type or null if there is no mention for this degree 312 */ 313 @Callable 314 public Map<String, String> getMentionContentTypes(List<String> degreeIds) 315 { 316 Map<String, String> mentionTypes = new HashMap<>(); 317 for (String degreeId : degreeIds) 318 { 319 mentionTypes.put(degreeId, getMentionForDegree(degreeId)); 320 } 321 return mentionTypes; 322 } 323 324 /** 325 * Get the mention for a given degree. 326 * @param degreeId The degree ID 327 * @return The associated mention reference table, null if there isn't 328 */ 329 public String getMentionForDegree(String degreeId) 330 { 331 try 332 { 333 Content content = _resolver.resolveById(degreeId); 334 return content.getValue(DEGREE_MENTION_TYPE); 335 } 336 catch (UnknownAmetysObjectException e) 337 { 338 // Nothing to do 339 } 340 return null; 341 } 342 343 /** 344 * Get the CDM-fr value associated with the given code 345 * @param tableRefId The id of content type 346 * @param code The code 347 * @return The CDM-fr value or empty string if not found 348 */ 349 public String getCDMfrValue (String tableRefId, String code) 350 { 351 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, tableRefId); 352 StringExpression codeExpr = new StringExpression(OdfReferenceTableEntry.CODE, Operator.EQ, code); 353 354 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, codeExpr)); 355 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 356 AmetysObjectIterator<Content> it = contents.iterator(); 357 358 if (it.hasNext()) 359 { 360 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(it.next()); 361 return entry.getCdmValue(); 362 } 363 364 return ""; 365 } 366 367 /** 368 * Get all items of an enumeration and their label 369 * @param tableRefId The id of content type 370 * @return items of enumeration 371 */ 372 public List<OdfReferenceTableEntry> getItems (String tableRefId) 373 { 374 return getItems(tableRefId, new SortField[0]); 375 } 376 377 /** 378 * Get all items of an enumeration and their label, sorted by given fields 379 * @param tableRefId The id of content type 380 * @param sortFields The sort fields to order results 381 * @return items of enumeration 382 */ 383 public List<OdfReferenceTableEntry> getItems (String tableRefId, SortField... sortFields) 384 { 385 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, tableRefId); 386 387 SortCriteria sortCriteria = new SortCriteria(); 388 for (SortField sortField : sortFields) 389 { 390 sortCriteria.addCriterion(sortField.getName(), sortField.getAscending(), sortField.getNormalize()); 391 } 392 393 String xpathQuery = ContentQueryHelper.getContentXPathQuery(cTypeExpr, sortCriteria); 394 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 395 396 return contents.stream().map(c -> new OdfReferenceTableEntry(c)).collect(Collectors.toList()); 397 } 398 399 /** 400 * Returns the label of an reference table entry 401 * @param contentId The content id 402 * @param lang The requested language of label 403 * @return the item label or <code>null</code> if not found 404 */ 405 public String getItemLabel(String contentId, String lang) 406 { 407 try 408 { 409 Content content = _resolver.resolveById(contentId); 410 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 411 return entry.getLabel(lang); 412 } 413 catch (UnknownAmetysObjectException e) 414 { 415 return null; 416 } 417 } 418 419 /** 420 * Returns the label of an reference table entry 421 * @param tableRefId The id of content type (useless) 422 * @param contentId The content id 423 * @param lang The requested language of label 424 * @return the item label or <code>null</code> if not found 425 * @deprecated Use {@link #getItemLabel(String, String)} instead 426 */ 427 @Deprecated 428 public String getItemLabel (String tableRefId, String contentId, String lang) 429 { 430 return getItemLabel(contentId, lang); 431 } 432 433 /** 434 * Returns the CMD value of an reference table entry 435 * @param contentId The content id 436 * @param returnCodeIfEmpty <code>true</code> to return the code if CDM-fr value is empty 437 * @return the CDM-fr value or empty value if not found 438 */ 439 public String getItemCDMfrValue(String contentId, boolean returnCodeIfEmpty) 440 { 441 if (StringUtils.isEmpty(contentId)) 442 { 443 return ""; 444 } 445 446 Content content = _resolver.resolveById(contentId); 447 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 448 449 String cdmValue = entry.getCdmValue(); 450 451 if (StringUtils.isEmpty(cdmValue) && returnCodeIfEmpty) 452 { 453 return entry.getCode(); 454 } 455 return cdmValue; 456 } 457 458 /** 459 * Returns the CMD value of an reference table entry 460 * @param tableRefId The id of content type (useless) 461 * @param contentId The content id 462 * @param returnCodeIfEmpty <code>true</code> to return the code if CDM-fr value is empty 463 * @return the CDM-fr value or empty value if not found 464 * @deprecated Use {@link #getItemCDMfrValue(String, boolean)} instead 465 */ 466 @Deprecated 467 public String getItemCDMfrValue (String tableRefId, String contentId, boolean returnCodeIfEmpty) 468 { 469 return getItemCDMfrValue(contentId, returnCodeIfEmpty); 470 } 471 472 /** 473 * Returns the code of an reference table entry from its CDM value 474 * @param contentId The id of content 475 * @return the code or empty value if not found 476 */ 477 public String getItemCode(String contentId) 478 { 479 if (StringUtils.isEmpty(contentId)) 480 { 481 return ""; 482 } 483 484 try 485 { 486 Content content = _resolver.resolveById(contentId); 487 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 488 return entry.getCode(); 489 } 490 catch (UnknownAmetysObjectException e) 491 { 492 return ""; 493 } 494 } 495 496 /** 497 * Returns the code of an reference table entry from its CDM value 498 * @param tableRefId The id of content type (useless) 499 * @param contentId The id of content 500 * @return the code or empty value if not found 501 * @deprecated Use {@link #getItemCode(String)} instead 502 */ 503 @Deprecated 504 public String getItemCode (String tableRefId, String contentId) 505 { 506 return getItemCode(contentId); 507 } 508 509 /** 510 * Returns the code of an reference table entry from its CDM value 511 * @param tableRefId The id of content type 512 * @param cdmValue The CDM-fr value 513 * @return the code or <code>null</code> if not found 514 */ 515 public String getItemCodeFromCDM (String tableRefId, String cdmValue) 516 { 517 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 518 StringExpression codeExpr = new StringExpression(OdfReferenceTableEntry.CDM_VALUE, Operator.EQ, cdmValue); 519 520 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, codeExpr)); 521 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 522 AmetysObjectIterator<Content> it = contents.iterator(); 523 524 if (it.hasNext()) 525 { 526 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(it.next()); 527 return entry.getCode(); 528 } 529 return null; 530 } 531 532 /** 533 * Returns the entry of an reference table entry from its cdmValue 534 * @param tableRefId The id of content type 535 * @param cdmValue The CDM-fr value 536 * @return the entry or <code>null</code> if not found 537 */ 538 public OdfReferenceTableEntry getItemFromCDM(String tableRefId, String cdmValue) 539 { 540 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 541 StringExpression cdmExpr = new StringExpression(OdfReferenceTableEntry.CDM_VALUE, Operator.EQ, cdmValue); 542 543 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, cdmExpr)); 544 545 return _resolver.<Content>query(xpathQuery).stream() 546 .findFirst() 547 .map(OdfReferenceTableEntry::new) 548 .orElse(null); 549 } 550 551 /** 552 * Returns the entry of an reference table entry from its code 553 * @param tableRefId The id of content type 554 * @param code The code 555 * @return the entry or <code>null</code> if not found 556 */ 557 public OdfReferenceTableEntry getItemFromCode(String tableRefId, String code) 558 { 559 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 560 StringExpression codeExpr = new StringExpression(OdfReferenceTableEntry.CODE, Operator.EQ, code); 561 562 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, codeExpr)); 563 564 return _resolver.<Content>query(xpathQuery).stream() 565 .findFirst() 566 .map(OdfReferenceTableEntry::new) 567 .orElse(null); 568 } 569 570 /** 571 * Returns the entry of a reference table entry from its code Apogee 572 * @param tableRefId The id of content type 573 * @param codeApogee The Apogee code 574 * @return the entry or <code>null</code> if not found 575 */ 576 public OdfReferenceTableEntry getItemFromApogee(String tableRefId, String codeApogee) 577 { 578 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 579 StringExpression cdmExpr = new StringExpression(OdfReferenceTableEntry.CODE_APOGEE, Operator.EQ, codeApogee); 580 581 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, cdmExpr)); 582 583 return _resolver.<Content>query(xpathQuery).stream() 584 .findFirst() 585 .map(OdfReferenceTableEntry::new) 586 .orElse(null); 587 } 588 589 private ContentTypeExpression _getContentTypeExpression(String tableRefId) 590 { 591 Set<String> tableRefids; 592 if (tableRefId.equals(OdfReferenceTableHelper.ABSTRACT_MENTION)) 593 { 594 tableRefids = Set.of(OdfReferenceTableHelper.MENTION_LICENCE, OdfReferenceTableHelper.MENTION_LICENCEPRO, OdfReferenceTableHelper.MENTION_MASTER); 595 } 596 else 597 { 598 tableRefids = Collections.singleton(tableRefId); 599 } 600 601 return new ContentTypeExpression(Operator.EQ, tableRefids.toArray(new String[tableRefids.size()])); 602 } 603 604 /** 605 * Returns the reference table entry from its CDM value 606 * @param contentId The id of content 607 * @return the item as an {@link OdfReferenceTableEntry} or null if not found 608 */ 609 public OdfReferenceTableEntry getItem(String contentId) 610 { 611 try 612 { 613 Content content = _resolver.resolveById(contentId); 614 return new OdfReferenceTableEntry(content); 615 } 616 catch (UnknownAmetysObjectException e) 617 { 618 // Can be an empty ID or an invalid ID (workspace or simply deleted element) 619 return null; 620 } 621 } 622 623 /** 624 * SAX items of a reference table 625 * @param contentHandler The content handler to sax into 626 * @param tableRefId The id of reference table 627 * @throws SAXException if an error occurred while saxing 628 */ 629 public void saxItems (ContentHandler contentHandler, String tableRefId) throws SAXException 630 { 631 _saxItems(contentHandler, new AttributesImpl(), tableRefId); 632 } 633 634 /** 635 * SAX items of a reference table 636 * @param contentHandler the content handler to sax into 637 * @param attributeDefinition the metadata definition 638 * @throws SAXException if an error occurs while saxing 639 */ 640 public void saxItems (ContentHandler contentHandler, ContentAttributeDefinition attributeDefinition) throws SAXException 641 { 642 String cTypeId = attributeDefinition.getContentTypeId(); 643 if (cTypeId.startsWith("odf-enumeration.")) 644 { 645 AttributesImpl attrs = new AttributesImpl(); 646 attrs.addCDATAAttribute("metadataName", attributeDefinition.getName()); 647 attrs.addCDATAAttribute("metadataPath", attributeDefinition.getPath()); 648 649 _saxItems(contentHandler, attrs, cTypeId); 650 } 651 } 652 653 private void _saxItems (ContentHandler contentHandler, AttributesImpl rootAttrs, String tableRefId) throws SAXException 654 { 655 rootAttrs.addCDATAAttribute("contentTypeId", tableRefId); 656 XMLUtils.startElement(contentHandler, "items", rootAttrs); 657 658 List<OdfReferenceTableEntry> entries = getItems(tableRefId); 659 for (OdfReferenceTableEntry entry : entries) 660 { 661 AttributesImpl valueAttrs = new AttributesImpl(); 662 valueAttrs.addCDATAAttribute("id", entry.getId()); 663 valueAttrs.addCDATAAttribute("order", entry.getOrder().toString()); 664 valueAttrs.addCDATAAttribute("code", entry.getCode()); 665 valueAttrs.addCDATAAttribute("cdmValue", entry.getCdmValue()); 666 667 String lang = Config.getInstance().getValue("odf.programs.lang"); 668 XMLUtils.createElement(contentHandler, "item", valueAttrs, entry.getLabel(lang)); 669 } 670 671 XMLUtils.endElement(contentHandler, "items"); 672 } 673 674 /** 675 * This class represents a sort field for reference table. 676 * 677 */ 678 public static final class SortField 679 { 680 private String _name; 681 private boolean _ascending; 682 private boolean _normalize; 683 684 /** 685 * Create a sort field 686 * @param name the name of field to sort on 687 * @param ascending <code>true</code> to sort in ascending order, <code>false</code> otherwise 688 */ 689 public SortField(String name, boolean ascending) 690 { 691 this(name, ascending, false); 692 } 693 694 /** 695 * Create a sort field 696 * @param name the name of field to sort on 697 * @param ascending <code>true</code> to sort in ascending order, <code>false</code> otherwise 698 * @param normalize <code>true</code> to normalize string properties (remove accents and lower case) 699 */ 700 public SortField(String name, boolean ascending, boolean normalize) 701 { 702 _name = name; 703 _ascending = ascending; 704 _normalize = normalize; 705 } 706 707 /** 708 * Get the name of the sort field 709 * @return the name of the sort field 710 */ 711 public String getName() 712 { 713 return _name; 714 } 715 716 /** 717 * Get the order for sorting results 718 * @return <code>true</code> to sort results in ascending order, <code>false</code> otherwise 719 */ 720 public boolean getAscending() 721 { 722 return _ascending; 723 } 724 725 /** 726 * Return the normalize status for this sort field 727 * @return <code>true</code> if string properties should be normalized (remove accents and lower case) 728 */ 729 public boolean getNormalize() 730 { 731 return _normalize; 732 } 733 734 } 735}