001/* 002 * Copyright 2015 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.plugins.thesaurus; 017 018import java.util.ArrayList; 019import java.util.HashMap; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.parameters.Parameters; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.acting.ServiceableAction; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.Redirector; 029import org.apache.cocoon.environment.Request; 030import org.apache.cocoon.environment.SourceResolver; 031import org.apache.commons.lang3.StringUtils; 032 033import org.ametys.cms.repository.Content; 034import org.ametys.core.cocoon.JSonReader; 035import org.ametys.core.util.I18nUtils; 036import org.ametys.plugins.repository.AmetysObject; 037import org.ametys.plugins.repository.AmetysObjectIterable; 038import org.ametys.plugins.repository.AmetysObjectResolver; 039import org.ametys.plugins.repository.TraversableAmetysObject; 040import org.ametys.plugins.thesaurus.content.ThesaurusItemContentType; 041import org.ametys.runtime.i18n.I18nizableText; 042 043/** 044 * Generates a subtree of the resources explorer. 045 */ 046public class GetTermsAction extends ServiceableAction 047{ 048 /** The Ametys object resolver */ 049 protected AmetysObjectResolver _resolver; 050 /** The thesaurus DAO */ 051 protected ThesaurusDAO _thesaurusDAO; 052 /** The I18n Utils */ 053 private I18nUtils _i18nUtils; 054 055 @Override 056 public void service(ServiceManager serviceManager) throws ServiceException 057 { 058 super.service(serviceManager); 059 _resolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE); 060 _thesaurusDAO = (ThesaurusDAO) serviceManager.lookup(ThesaurusDAO.ROLE); 061 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 062 } 063 064 @SuppressWarnings("unchecked") 065 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 066 { 067 Map jsParameters = (Map<String, Object>) objectModel.get(ObjectModelHelper.PARENT_CONTEXT); 068 069 String parentId = (String) jsParameters.get("node"); 070 boolean hideCandidates = (boolean) jsParameters.get("hideCandidates"); 071 boolean checkMode = (boolean) jsParameters.get("checkMode"); 072 073 List<Map<String, Object>> nodes = new ArrayList<>(); 074 075 TraversableAmetysObject parent = _resolver.hasAmetysObjectForId(parentId) ? (TraversableAmetysObject) _resolver.resolveById(parentId) : null; 076 077 if (parent != null) 078 { 079 try (AmetysObjectIterable<Content> terms = _thesaurusDAO.getChildTerms(parentId)) 080 { 081 for (Content term : terms) 082 { 083 nodes.add(termToJSON(term, parent instanceof Content ? (Content) parent : null, checkMode)); 084 } 085 } 086 } 087 088 if (parent instanceof MicroThesaurus && !hideCandidates) 089 { 090 if (parent.hasChild(ThesaurusDAO.ROOT_CANDIDATES_NODENAME)) 091 { 092 TraversableAmetysObject rootCandidates = parent.getChild(ThesaurusDAO.ROOT_CANDIDATES_NODENAME); 093 nodes.add(rootCandidatesToJSON(rootCandidates)); 094 } 095 } 096 097 Map<String, Object> result = new HashMap<>(); 098 result.put("children", nodes); 099 100 Request request = ObjectModelHelper.getRequest(objectModel); 101 request.setAttribute(JSonReader.OBJECT_TO_READ, result); 102 103 return EMPTY_MAP; 104 } 105 106 /** 107 * Gets the root candidates to JSON format 108 * @param rootCandidates The root node for candidates 109 * @return The candidates' properties 110 */ 111 protected Map<String, Object> rootCandidatesToJSON(TraversableAmetysObject rootCandidates) 112 { 113 Map<String, Object> infos = new HashMap<>(); 114 115 infos.put("id", rootCandidates.getId()); 116 infos.put("name", rootCandidates.getName()); 117 infos.put("label", _i18nUtils.translate(new I18nizableText("plugin.thesaurus", "PLUGINS_THESAURUS_CONTENT_TYPE_CANDIDATES_LABEL"))); 118 infos.put("type", "root-candidates"); 119 120 return infos; 121 } 122 123 /** 124 * Gets a term to JSON format 125 * @param term The term 126 * @param genericTerm The generic term. Can be null. 127 * @param checkMode True for checked mode 128 * @return The term's properties 129 */ 130 protected Map<String, Object> termToJSON(Content term, Content genericTerm, boolean checkMode) 131 { 132 Map<String, Object> infos = new HashMap<>(); 133 134 String type = term.getTypes()[0]; 135 136 infos.put("id", term.getId()); 137 infos.put("name", term.getName()); 138 infos.put("label", term.getTitle()); 139 140 if (ThesaurusItemContentType.TERM_CONTENT_TYPE_ID.equals(type)) 141 { 142 infos.put("type", "term"); 143 144 // Related terms 145 String ta = _getRelatedTerms(term); 146 if (StringUtils.isNotEmpty(ta)) 147 { 148 infos.put("ta", ta); 149 } 150 151 // Specifics terms 152 String ts = _getSpecificTerms(term); 153 if (StringUtils.isNotEmpty(ts)) 154 { 155 infos.put("ts", ts); 156 infos.put("leaf", "false"); 157 } 158 else 159 { 160 infos.put("leaf", "true"); 161 } 162 163 // Synonyms 164 if (term.getMetadataHolder().hasMetadata(ThesaurusDAO.METADATA_SYNONYMS)) 165 { 166 String[] synonyms = term.getMetadataHolder().getStringArray(ThesaurusDAO.METADATA_SYNONYMS); 167 infos.put("synonyms", StringUtils.join(synonyms, ", ")); 168 } 169 170 // Generic term 171 if (genericTerm != null) 172 { 173 infos.put("tg", genericTerm.getTitle()); 174 } 175 } 176 else if (ThesaurusItemContentType.CANDIDAT_CONTENT_TYPE_ID.equals(type)) 177 { 178 infos.put("type", "candidate"); 179 infos.put("leaf", "true"); 180 infos.put("comment", term.getMetadataHolder().getString("comment", "")); 181 } 182 183 if (checkMode) 184 { 185 infos.put("checked", "false"); 186 } 187 188 return infos; 189 } 190 191 private String _getRelatedTerms (Content term) 192 { 193 List<String> relatedTerms = new ArrayList<>(); 194 195 if (term.getMetadataHolder().hasMetadata(ThesaurusDAO.METADATA_RELATED_TERMS)) 196 { 197 String[] ids = term.getMetadataHolder().getStringArray(ThesaurusDAO.METADATA_RELATED_TERMS); 198 for (String id : ids) 199 { 200 Content relatedTerm = _resolver.resolveById(id); 201 relatedTerms.add(relatedTerm.getTitle()); 202 } 203 } 204 205 return StringUtils.join(relatedTerms, ", "); 206 } 207 208 private String _getSpecificTerms (Content term) 209 { 210 List<String> specificTerms = new ArrayList<>(); 211 212 if (term.getMetadataHolder().hasMetadata(ThesaurusDAO.METADATA_SPECIFIC_TERMS)) 213 { 214 TraversableAmetysObject ts = term.getMetadataHolder().getObjectCollection(ThesaurusDAO.METADATA_SPECIFIC_TERMS); 215 for (AmetysObject child : ts.getChildren()) 216 { 217 if (child instanceof Content) 218 { 219 specificTerms.add(((Content) child).getTitle()); 220 } 221 } 222 } 223 224 return StringUtils.join(specificTerms, ", "); 225 } 226 227}