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 174 private AmetysObjectResolver _resolver; 175 176 private ContentTypeExtensionPoint _cTypeEP; 177 178 private ContentTypesHelper _cTypeHelper; 179 180 @Override 181 public void service(ServiceManager manager) throws ServiceException 182 { 183 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 184 _cTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 185 _cTypeHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 186 } 187 188 /** 189 * Determines if the content type is a ODF table reference 190 * @param cTypeId The id of content type 191 * @return true if the content type is a ODF table reference 192 */ 193 public boolean isTableReference(String cTypeId) 194 { 195 return _cTypeHelper.getAncestors(cTypeId).contains(ABSTRACT_TABLE_REF); 196 } 197 198 /** 199 * Determines if the content is an entry of a ODF table reference 200 * @param content The content 201 * @return <code>true</code> if the content is an entry of a ODF table reference 202 */ 203 public boolean isTableReferenceEntry(Content content) 204 { 205 String[] cTypeIds = content.getTypes(); 206 for (String cTypeId : cTypeIds) 207 { 208 if (isTableReference(cTypeId)) 209 { 210 return true; 211 } 212 } 213 return false; 214 } 215 216 /** 217 * Get the id of table references 218 * @return The content type's id 219 */ 220 public Set<String> getTableReferenceIds() 221 { 222 Set<String> tableRefIds = new HashSet<>(); 223 224 for (String cTypeId : _cTypeEP.getExtensionsIds()) 225 { 226 if (_cTypeHelper.getAncestors(cTypeId).contains(ABSTRACT_TABLE_REF)) 227 { 228 tableRefIds.add(cTypeId); 229 } 230 } 231 return tableRefIds; 232 } 233 234 /** 235 * Get the attribute definitions for table references for a given content type 236 * @param cTypeId The id of content type 237 * @return The attribute definitions for table references 238 */ 239 public Map<String, ContentAttributeDefinition> getTableRefAttributeDefinitions(String cTypeId) 240 { 241 ContentType cType = _cTypeEP.getExtension(cTypeId); 242 return _getTableRefAttributes(cType); 243 } 244 245 private Map<String, ContentAttributeDefinition> _getTableRefAttributes(ModelItemContainer modelItemContainer) 246 { 247 Map<String, ContentAttributeDefinition> tableRefAttributes = new LinkedHashMap<>(); 248 249 for (ModelItem modelItem : modelItemContainer.getModelItems()) 250 { 251 if (modelItem instanceof ContentAttributeDefinition) 252 { 253 ContentAttributeDefinition attributeDefinition = (ContentAttributeDefinition) modelItem; 254 if (isTableReference(attributeDefinition.getContentTypeId())) 255 { 256 tableRefAttributes.put(attributeDefinition.getPath(), attributeDefinition); 257 } 258 } 259 else if (modelItem instanceof ModelItemContainer && !(modelItem instanceof RepeaterDefinition)) 260 { 261 // enumerated attributes in repeaters are not supported 262 tableRefAttributes.putAll(_getTableRefAttributes((ModelItemContainer) modelItem)); 263 } 264 } 265 266 return tableRefAttributes; 267 } 268 269 /** 270 * Get the attribute definitions for table references for a given content type and a view 271 * @param cTypeId The id of content type 272 * @param viewName the name of the view. Cannot be null. 273 * @return The attributes definitions for table references 274 */ 275 public Map<String, ContentAttributeDefinition> getTableRefAttributeDefinitions(String cTypeId, String viewName) 276 { 277 ContentType cType = _cTypeEP.getExtension(cTypeId); 278 279 View view = cType.getView(viewName); 280 return _getTableRefAttributes(view); 281 } 282 283 private Map<String, ContentAttributeDefinition> _getTableRefAttributes(ViewItemContainer viewItemContainer) 284 { 285 Map<String, ContentAttributeDefinition> tableRefAttributes = new LinkedHashMap<>(); 286 287 for (ViewItem viewItem : viewItemContainer.getViewItems()) 288 { 289 if (viewItem instanceof ViewElement) 290 { 291 ElementDefinition definition = ((ViewElement) viewItem).getDefinition(); 292 if (definition instanceof ContentAttributeDefinition) 293 { 294 tableRefAttributes.put(definition.getPath(), (ContentAttributeDefinition) definition); 295 } 296 } 297 else if (viewItem instanceof ViewItemContainer) 298 { 299 tableRefAttributes.putAll(_getTableRefAttributes((ViewItemContainer) viewItem)); 300 } 301 } 302 303 return tableRefAttributes; 304 } 305 306 /** 307 * Get the content type for mention for this degree 308 * @param degreeIds The ids of degrees 309 * @return A map with the id of content type or null if there is no mention for this degree 310 */ 311 @Callable 312 public Map<String, String> getMentionContentTypes(List<String> degreeIds) 313 { 314 Map<String, String> mentionTypes = new HashMap<>(); 315 for (String degreeId : degreeIds) 316 { 317 mentionTypes.put(degreeId, getMentionForDegree(degreeId)); 318 } 319 return mentionTypes; 320 } 321 322 /** 323 * Get the mention for a given degree. 324 * @param degreeId The degree ID 325 * @return The associated mention reference table, null if there isn't 326 */ 327 public String getMentionForDegree(String degreeId) 328 { 329 try 330 { 331 Content content = _resolver.resolveById(degreeId); 332 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 333 334 String degreeCode = entry.getCode(); 335 336 if (degreeCode.equals(Config.getInstance().getValue("odf.programs.degree.license"))) 337 { 338 return OdfReferenceTableHelper.MENTION_LICENCE; 339 } 340 else if (degreeCode.equals(Config.getInstance().getValue("odf.programs.degree.licensepro"))) 341 { 342 return OdfReferenceTableHelper.MENTION_LICENCEPRO; 343 } 344 else if (degreeCode.equals(Config.getInstance().getValue("odf.programs.degree.master"))) 345 { 346 return OdfReferenceTableHelper.MENTION_MASTER; 347 } 348 } 349 catch (UnknownAmetysObjectException e) 350 { 351 // Nothing to do 352 } 353 return null; 354 } 355 356 /** 357 * Get the CDM-fr value associated with the given code 358 * @param tableRefId The id of content type 359 * @param code The code 360 * @return The CDM-fr value or empty string if not found 361 */ 362 public String getCDMfrValue (String tableRefId, String code) 363 { 364 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, tableRefId); 365 StringExpression codeExpr = new StringExpression(OdfReferenceTableEntry.CODE, Operator.EQ, code); 366 367 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, codeExpr)); 368 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 369 AmetysObjectIterator<Content> it = contents.iterator(); 370 371 if (it.hasNext()) 372 { 373 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(it.next()); 374 return entry.getCdmValue(); 375 } 376 377 return ""; 378 } 379 380 /** 381 * Get all items of an enumeration and their label 382 * @param tableRefId The id of content type 383 * @return items of enumeration 384 */ 385 public List<OdfReferenceTableEntry> getItems (String tableRefId) 386 { 387 return getItems(tableRefId, new SortField[0]); 388 } 389 390 /** 391 * Get all items of an enumeration and their label, sorted by given fields 392 * @param tableRefId The id of content type 393 * @param sortFields The sort fields to order results 394 * @return items of enumeration 395 */ 396 public List<OdfReferenceTableEntry> getItems (String tableRefId, SortField... sortFields) 397 { 398 ContentTypeExpression cTypeExpr = new ContentTypeExpression(Operator.EQ, tableRefId); 399 400 SortCriteria sortCriteria = new SortCriteria(); 401 for (SortField sortField : sortFields) 402 { 403 sortCriteria.addCriterion(sortField.getName(), sortField.getAscending(), sortField.getNormalize()); 404 } 405 406 String xpathQuery = ContentQueryHelper.getContentXPathQuery(cTypeExpr, sortCriteria); 407 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 408 409 return contents.stream().map(c -> new OdfReferenceTableEntry(c)).collect(Collectors.toList()); 410 } 411 412 /** 413 * Returns the label of an reference table entry 414 * @param contentId The content id 415 * @param lang The requested language of label 416 * @return the item label or <code>null</code> if not found 417 */ 418 public String getItemLabel(String contentId, String lang) 419 { 420 try 421 { 422 Content content = _resolver.resolveById(contentId); 423 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 424 return entry.getLabel(lang); 425 } 426 catch (UnknownAmetysObjectException e) 427 { 428 return null; 429 } 430 } 431 432 /** 433 * Returns the label of an reference table entry 434 * @param tableRefId The id of content type (useless) 435 * @param contentId The content id 436 * @param lang The requested language of label 437 * @return the item label or <code>null</code> if not found 438 * @deprecated Use {@link #getItemLabel(String, String)} instead 439 */ 440 @Deprecated 441 public String getItemLabel (String tableRefId, String contentId, String lang) 442 { 443 return getItemLabel(contentId, lang); 444 } 445 446 /** 447 * Returns the CMD value of an reference table entry 448 * @param contentId The content id 449 * @param returnCodeIfEmpty <code>true</code> to return the code if CDM-fr value is empty 450 * @return the CDM-fr value or empty value if not found 451 */ 452 public String getItemCDMfrValue(String contentId, boolean returnCodeIfEmpty) 453 { 454 if (StringUtils.isEmpty(contentId)) 455 { 456 return ""; 457 } 458 459 Content content = _resolver.resolveById(contentId); 460 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 461 462 String cdmValue = entry.getCdmValue(); 463 464 if (StringUtils.isEmpty(cdmValue) && returnCodeIfEmpty) 465 { 466 return entry.getCode(); 467 } 468 return cdmValue; 469 } 470 471 /** 472 * Returns the CMD value of an reference table entry 473 * @param tableRefId The id of content type (useless) 474 * @param contentId The content id 475 * @param returnCodeIfEmpty <code>true</code> to return the code if CDM-fr value is empty 476 * @return the CDM-fr value or empty value if not found 477 * @deprecated Use {@link #getItemCDMfrValue(String, boolean)} instead 478 */ 479 @Deprecated 480 public String getItemCDMfrValue (String tableRefId, String contentId, boolean returnCodeIfEmpty) 481 { 482 return getItemCDMfrValue(contentId, returnCodeIfEmpty); 483 } 484 485 /** 486 * Returns the code of an reference table entry from its CDM value 487 * @param contentId The id of content 488 * @return the code or empty value if not found 489 */ 490 public String getItemCode(String contentId) 491 { 492 if (StringUtils.isEmpty(contentId)) 493 { 494 return ""; 495 } 496 497 try 498 { 499 Content content = _resolver.resolveById(contentId); 500 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(content); 501 return entry.getCode(); 502 } 503 catch (UnknownAmetysObjectException e) 504 { 505 return ""; 506 } 507 } 508 509 /** 510 * Returns the code of an reference table entry from its CDM value 511 * @param tableRefId The id of content type (useless) 512 * @param contentId The id of content 513 * @return the code or empty value if not found 514 * @deprecated Use {@link #getItemCode(String)} instead 515 */ 516 @Deprecated 517 public String getItemCode (String tableRefId, String contentId) 518 { 519 return getItemCode(contentId); 520 } 521 522 /** 523 * Returns the code of an reference table entry from its CDM value 524 * @param tableRefId The id of content type 525 * @param cdmValue The CDM-fr value 526 * @return the code or <code>null</code> if not found 527 */ 528 public String getItemCodeFromCDM (String tableRefId, String cdmValue) 529 { 530 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 531 StringExpression codeExpr = new StringExpression(OdfReferenceTableEntry.CDM_VALUE, Operator.EQ, cdmValue); 532 533 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, codeExpr)); 534 AmetysObjectIterable<Content> contents = _resolver.query(xpathQuery); 535 AmetysObjectIterator<Content> it = contents.iterator(); 536 537 if (it.hasNext()) 538 { 539 OdfReferenceTableEntry entry = new OdfReferenceTableEntry(it.next()); 540 return entry.getCode(); 541 } 542 return null; 543 } 544 545 /** 546 * Returns the entry of an reference table entry from its cdmValue 547 * @param tableRefId The id of content type 548 * @param cdmValue The CDM-fr value 549 * @return the entry or <code>null</code> if not found 550 */ 551 public OdfReferenceTableEntry getItemFromCDM(String tableRefId, String cdmValue) 552 { 553 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 554 StringExpression cdmExpr = new StringExpression(OdfReferenceTableEntry.CDM_VALUE, Operator.EQ, cdmValue); 555 556 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, cdmExpr)); 557 558 return _resolver.<Content>query(xpathQuery).stream() 559 .findFirst() 560 .map(OdfReferenceTableEntry::new) 561 .orElse(null); 562 } 563 564 /** 565 * Returns the entry of an reference table entry from its code 566 * @param tableRefId The id of content type 567 * @param code The code 568 * @return the entry or <code>null</code> if not found 569 */ 570 public OdfReferenceTableEntry getItemFromCode(String tableRefId, String code) 571 { 572 ContentTypeExpression cTypeExpr = _getContentTypeExpression(tableRefId); 573 StringExpression codeExpr = new StringExpression(OdfReferenceTableEntry.CODE, Operator.EQ, code); 574 575 String xpathQuery = ContentQueryHelper.getContentXPathQuery(new AndExpression(cTypeExpr, codeExpr)); 576 577 return _resolver.<Content>query(xpathQuery).stream() 578 .findFirst() 579 .map(OdfReferenceTableEntry::new) 580 .orElse(null); 581 } 582 583 private ContentTypeExpression _getContentTypeExpression(String tableRefId) 584 { 585 Set<String> tableRefids; 586 if (tableRefId.equals(OdfReferenceTableHelper.ABSTRACT_MENTION)) 587 { 588 tableRefids = Set.of(OdfReferenceTableHelper.MENTION_LICENCE, OdfReferenceTableHelper.MENTION_LICENCEPRO, OdfReferenceTableHelper.MENTION_MASTER); 589 } 590 else 591 { 592 tableRefids = Collections.singleton(tableRefId); 593 } 594 595 return new ContentTypeExpression(Operator.EQ, tableRefids.toArray(new String[tableRefids.size()])); 596 } 597 598 /** 599 * Returns the reference table entry from its CDM value 600 * @param contentId The id of content 601 * @return the item as an {@link OdfReferenceTableEntry} or null if not found 602 */ 603 public OdfReferenceTableEntry getItem(String contentId) 604 { 605 try 606 { 607 Content content = _resolver.resolveById(contentId); 608 return new OdfReferenceTableEntry(content); 609 } 610 catch (UnknownAmetysObjectException e) 611 { 612 // Can be an empty ID or an invalid ID (workspace or simply deleted element) 613 return null; 614 } 615 } 616 617 /** 618 * SAX items of a reference table 619 * @param contentHandler The content handler to sax into 620 * @param tableRefId The id of reference table 621 * @throws SAXException if an error occurred while saxing 622 */ 623 public void saxItems (ContentHandler contentHandler, String tableRefId) throws SAXException 624 { 625 _saxItems(contentHandler, new AttributesImpl(), tableRefId); 626 } 627 628 /** 629 * SAX items of a reference table 630 * @param contentHandler the content handler to sax into 631 * @param attributeDefinition the metadata definition 632 * @throws SAXException if an error occurs while saxing 633 */ 634 public void saxItems (ContentHandler contentHandler, ContentAttributeDefinition attributeDefinition) throws SAXException 635 { 636 String cTypeId = attributeDefinition.getContentTypeId(); 637 if (cTypeId.startsWith("odf-enumeration.")) 638 { 639 AttributesImpl attrs = new AttributesImpl(); 640 attrs.addCDATAAttribute("metadataName", attributeDefinition.getName()); 641 attrs.addCDATAAttribute("metadataPath", attributeDefinition.getPath()); 642 643 _saxItems(contentHandler, attrs, cTypeId); 644 } 645 } 646 647 private void _saxItems (ContentHandler contentHandler, AttributesImpl rootAttrs, String tableRefId) throws SAXException 648 { 649 rootAttrs.addCDATAAttribute("contentTypeId", tableRefId); 650 XMLUtils.startElement(contentHandler, "items", rootAttrs); 651 652 List<OdfReferenceTableEntry> entries = getItems(tableRefId); 653 for (OdfReferenceTableEntry entry : entries) 654 { 655 AttributesImpl valueAttrs = new AttributesImpl(); 656 valueAttrs.addCDATAAttribute("id", entry.getId()); 657 valueAttrs.addCDATAAttribute("order", entry.getOrder().toString()); 658 valueAttrs.addCDATAAttribute("code", entry.getCode()); 659 valueAttrs.addCDATAAttribute("cdmValue", entry.getCdmValue()); 660 661 String lang = Config.getInstance().getValue("odf.programs.lang"); 662 XMLUtils.createElement(contentHandler, "item", valueAttrs, entry.getLabel(lang)); 663 } 664 665 XMLUtils.endElement(contentHandler, "items"); 666 } 667 668 /** 669 * This class represents a sort field for reference table. 670 * 671 */ 672 public static final class SortField 673 { 674 private String _name; 675 private boolean _ascending; 676 private boolean _normalize; 677 678 /** 679 * Create a sort field 680 * @param name the name of field to sort on 681 * @param ascending <code>true</code> to sort in ascending order, <code>false</code> otherwise 682 */ 683 public SortField(String name, boolean ascending) 684 { 685 this(name, ascending, false); 686 } 687 688 /** 689 * Create a sort field 690 * @param name the name of field to sort on 691 * @param ascending <code>true</code> to sort in ascending order, <code>false</code> otherwise 692 * @param normalize <code>true</code> to normalize string properties (remove accents and lower case) 693 */ 694 public SortField(String name, boolean ascending, boolean normalize) 695 { 696 _name = name; 697 _ascending = ascending; 698 _normalize = normalize; 699 } 700 701 /** 702 * Get the name of the sort field 703 * @return the name of the sort field 704 */ 705 public String getName() 706 { 707 return _name; 708 } 709 710 /** 711 * Get the order for sorting results 712 * @return <code>true</code> to sort results in ascending order, <code>false</code> otherwise 713 */ 714 public boolean getAscending() 715 { 716 return _ascending; 717 } 718 719 /** 720 * Return the normalize status for this sort field 721 * @return <code>true</code> if string properties should be normalized (remove accents and lower case) 722 */ 723 public boolean getNormalize() 724 { 725 return _normalize; 726 } 727 728 } 729}