View Javadoc
1   /*
2    * Copyright 2010 James Pether Sörling
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   *	$Id$
17   *  $HeadURL$
18  */
19  package com.hack23.cia.service.external.riksdagen.impl;
20  
21  import java.text.ParseException;
22  import java.text.SimpleDateFormat;
23  import java.util.ArrayList;
24  import java.util.Date;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Locale;
28  import java.util.Set;
29  
30  import javax.xml.bind.JAXBElement;
31  
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  import org.springframework.beans.factory.annotation.Autowired;
35  import org.springframework.beans.factory.annotation.Qualifier;
36  import org.springframework.oxm.Unmarshaller;
37  import org.springframework.stereotype.Component;
38  
39  import com.hack23.cia.model.external.riksdagen.votering.impl.BallotContainer;
40  import com.hack23.cia.model.external.riksdagen.votering.impl.VoteData;
41  import com.hack23.cia.model.external.riksdagen.votering.impl.VoteDataDto;
42  import com.hack23.cia.model.external.riksdagen.votering.impl.VoteDataEmbeddedId;
43  import com.hack23.cia.model.external.riksdagen.voteringlista.impl.BallotDocumentElement;
44  import com.hack23.cia.model.external.riksdagen.voteringlista.impl.VoteListContainerElement;
45  import com.hack23.cia.service.external.common.api.XmlAgent;
46  import com.hack23.cia.service.external.riksdagen.api.DataFailureException;
47  import com.hack23.cia.service.external.riksdagen.api.RiksdagenBallotApi;
48  
49  /**
50   * The Class RiksdagenBallotApiImpl.
51   */
52  @Component
53  final class RiksdagenBallotApiImpl implements RiksdagenBallotApi {
54  
55  	/** The Constant BALLOT. */
56  	private static final String BALLOT = "http://data.riksdagen.se/votering/${ID_KEY}/xml";
57  
58  	/** The Constant BALLOT_LIST. */
59  	private static final String BALLOT_LIST="http://data.riksdagen.se/voteringlista/?rm=&bet=&punkt=&iid=&parti=&valkrets=&rost=&sz=10000&utformat=xml&gruppering=votering_id";
60  
61  	/** The Constant CONTAINS_ONE. */
62  	private static final int CONTAINS_ONE = 1;
63  
64  	/**
65  	 * The Constant HTTP_VOTERING_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL.
66  	 */
67  	private static final String HTTP_VOTERING_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL = "http://votering.riksdagen.external.model.cia.hack23.com/impl";
68  
69  	/**
70  	 * The Constant
71  	 * HTTP_VOTERINGLISTA_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL.
72  	 */
73  	private static final String HTTP_VOTERINGLISTA_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL = "http://voteringlista.riksdagen.external.model.cia.hack23.com/impl";
74  
75  
76  	/** The Constant ID_KEY. */
77  	private static final String ID_KEY = "${ID_KEY}";
78  
79  	/** The Constant LOGGER. */
80  	private static final Logger LOGGER = LoggerFactory
81  			.getLogger(RiksdagenBallotApiImpl.class);
82  
83  	/** The Constant PROBLEM_GETTING_BALLOT_ID_S_FROM_DATA_RIKSDAGEN_SE. */
84  	private static final String PROBLEM_GETTING_BALLOT_ID_S_FROM_DATA_RIKSDAGEN_SE = "Problem getting ballot id:{} from data.riksdagen.se";
85  
86  	/** The Constant PROBLEM_GETTING_BALLOT_LIST_FROM_DATA_RIKSDAGEN_SE. */
87  	private static final String PROBLEM_GETTING_BALLOT_LIST_FROM_DATA_RIKSDAGEN_SE = "Problem getting ballot list from data.riksdagen.se";
88  
89  	/** The Constant YYYY_MM_DD. */
90  	private static final String YYYY_MM_DD = "yyyy-MM-dd";
91  
92  	/** The riksdagen ballot list marshaller. */
93  	@Autowired
94  	@Qualifier("riksdagenBallotListMarshaller")
95  	private Unmarshaller riksdagenBallotListMarshaller;
96  
97  
98  	/** The riksdagen ballot marshaller. */
99  	@Autowired
100 	@Qualifier("riksdagenBallotMarshaller")
101 	private Unmarshaller riksdagenBallotMarshaller;
102 
103 	/** The xml agent. */
104 	@Autowired
105 	private XmlAgent xmlAgent;
106 
107 
108 	/**
109 	 * Instantiates a new riksdagen ballot api impl.
110 	 */
111 	public RiksdagenBallotApiImpl() {
112 		super();
113 	}
114 
115 
116 	/**
117 	 * Best guess vote date.
118 	 *
119 	 * @param ballotContainer
120 	 *            the ballot container
121 	 * @return the date
122 	 * @throws ParseException
123 	 *             the parse exception
124 	 */
125 	private static Date bestGuessVoteDate(final BallotContainer ballotContainer) throws ParseException {
126 		final com.hack23.cia.model.external.riksdagen.votering.impl.BallotDocumentElement ballotDocumentElement = ballotContainer.getBallotDocumentElement();
127 		Date result;
128 
129 		final String createdDate=ballotContainer.getBallotDocumentElement().getCreatedDate();
130 
131 		if(createdDate!= null && createdDate.length()>= YYYY_MM_DD.length()) {
132 			result=new SimpleDateFormat(YYYY_MM_DD,Locale.ENGLISH).parse(createdDate);
133 		} else {
134 			final String systemDate = ballotDocumentElement.getSystemDate();
135 
136 			if(systemDate!= null && systemDate.length()>= YYYY_MM_DD.length()) {
137 				result=new SimpleDateFormat(YYYY_MM_DD,Locale.ENGLISH).parse(systemDate);
138 			} else {
139 				result=new SimpleDateFormat(YYYY_MM_DD,Locale.ENGLISH).parse(ballotDocumentElement.getMadePublicDate());
140 			}
141 		}
142 		return result;
143 	}
144 
145 	/**
146 	 * Check same date.
147 	 *
148 	 * @param voteList
149 	 *            the vote list
150 	 * @return the date
151 	 * @throws ParseException
152 	 *             the parse exception
153 	 */
154 	private static Date checkSameDate(final List<VoteDataDto> voteList) throws ParseException {
155 		final Set<String> set = new HashSet<>();
156 		Date result=null;
157 
158 		for (final VoteDataDto voteData : voteList) {
159 			final String voteDate = voteData.getVoteDate();
160 			if (voteDate !=null && voteDate.length() >= YYYY_MM_DD.length()) {
161 				set.add(voteData.getVoteDate());
162 			}
163 		}
164 
165 		if (set.size() ==CONTAINS_ONE) {
166 			final String dateString = set.iterator().next();
167 			result=new SimpleDateFormat(YYYY_MM_DD,Locale.ENGLISH).parse(dateString);
168 		}
169 		return result;
170 	}
171 
172 	/**
173 	 * Try to find valid vote date.
174 	 *
175 	 * @param ballotContainer
176 	 *            the ballot container
177 	 * @param voteDataList
178 	 *            the vote data list
179 	 * @return the date
180 	 * @throws ParseException
181 	 *             the parse exception
182 	 */
183 	private static Date tryToFindValidVoteDate(final BallotContainer ballotContainer, final List<VoteDataDto> voteDataList)
184 					throws ParseException {
185 		Date ballotDate;
186 		final Date sameDate = checkSameDate(voteDataList);
187 
188 		if (sameDate != null) {
189 			ballotDate = sameDate;
190 		} else {
191 			ballotDate = bestGuessVoteDate(ballotContainer);
192 		}
193 		return ballotDate;
194 	}
195 
196 
197 	@Override
198 	public List<VoteData> getBallot(final String id) throws DataFailureException {
199 		final String url = BALLOT.replace(ID_KEY, id);
200 
201 		final BallotContainer ballotContainer;
202 		try {
203 			ballotContainer = ((JAXBElement<BallotContainer>) xmlAgent.unmarshallXml(
204 					riksdagenBallotMarshaller, url,
205 					HTTP_VOTERING_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL,null,null))
206 					.getValue();
207 
208 			final List<VoteDataDto> voteDataList = ballotContainer.getBallotDocumentData().getVoteDataList();
209 
210 			final Date ballotDate=tryToFindValidVoteDate(ballotContainer, voteDataList);
211 
212 			final List<VoteData> result = new ArrayList<>();
213 			for (final VoteDataDto voteDataDto: voteDataList) {
214 				final VoteData voteData= new VoteData().withEmbeddedId(new VoteDataEmbeddedId().withBallotId(voteDataDto.getBallotId()).withIntressentId(voteDataDto.getIntressentId()).withIssue(voteDataDto.getIssue()).withConcern(voteDataDto.getConcern()));
215 
216 				voteData.setBankNumber(voteDataDto.getBankNumber());
217 				voteData.setLabel(voteDataDto.getLabel());
218 				voteData.setLastName(voteDataDto.getLastName());
219 				voteData.setBornYear(voteDataDto.getBornYear());
220 				voteData.setFirstName(voteDataDto.getFirstName());
221 				voteData.setPlace(voteDataDto.getPlace());
222 				voteData.setGender(voteDataDto.getGender());
223 				voteData.setFullName(voteDataDto.getFullName());
224 				voteData.setParty(voteDataDto.getParty().toUpperCase(Locale.ENGLISH));
225 				voteData.setRm(voteDataDto.getRm());
226 				voteData.setVote(voteDataDto.getVote());
227 				voteData.setBallotType(voteDataDto.getBallotType());
228 				voteData.setElectoralRegionNumber(voteDataDto.getElectoralRegionNumber());
229 				voteData.setElectoralRegion(voteDataDto.getElectoralRegion());
230 
231 				voteData.setVoteDate(ballotDate);
232 
233 				result.add(voteData);
234 			}
235 
236 
237 			return result;
238 
239 		} catch (final Exception e) {
240 			LOGGER.warn(PROBLEM_GETTING_BALLOT_ID_S_FROM_DATA_RIKSDAGEN_SE,id);
241 			throw new DataFailureException(e);
242 		}
243 
244 
245 
246 	}
247 
248 	@Override
249 	public List<BallotDocumentElement> getBallotList() throws DataFailureException {
250 
251 		try {
252 			final String url = BALLOT_LIST;
253 			return ((JAXBElement<VoteListContainerElement>) xmlAgent.unmarshallXml(riksdagenBallotListMarshaller, url,
254 							HTTP_VOTERINGLISTA_RIKSDAGEN_EXTERNAL_MODEL_CIA_HACK23_COM_IMPL,null,null))
255 							.getValue().getVotering();
256 		} catch (final Exception e) {
257 			LOGGER.warn(PROBLEM_GETTING_BALLOT_LIST_FROM_DATA_RIKSDAGEN_SE);
258 			throw new DataFailureException(e);
259 		}
260 	}
261 }