]> git.uio.no Git - cristin-ws.git/blob - src/no/usit/fridaws/ProsjektArbeidEgenXML.java
1e19dea55012e824e1ee9d7361cd258c96c69266
[cristin-ws.git] / src / no / usit / fridaws / ProsjektArbeidEgenXML.java
1 package no.usit.fridaws;
2
3 import java.sql.Connection;
4 import java.sql.PreparedStatement;
5 import java.sql.ResultSet;
6 import java.sql.SQLException;
7 import java.util.ArrayList;
8 import java.util.Hashtable;
9 import java.util.List;
10
11 import javax.ws.rs.GET;
12 import javax.ws.rs.Path;
13 import javax.ws.rs.QueryParam;
14 import javax.ws.rs.core.MediaType;
15 import javax.ws.rs.core.Response;
16 import javax.ws.rs.core.Variant;
17
18 import org.jboss.resteasy.annotations.cache.Cache;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 /**
23  * <p>Arbeider for et prosjekt</p>
24  * 
25  * <p>Tjenesten returnerer publikasjoner basert på finansieringskilde.</p>
26  * 
27  * @author leivhe
28  * @see https://utv.uio.no/jira/browse/CRISWS-35
29  */
30 @Path("/hentArbeiderForProsjektEgenXML")
31 public class ProsjektArbeidEgenXML {
32
33         private static final Logger log = LoggerFactory.getLogger(ProsjektArbeidEgenXML.class);
34
35         /**
36          * Returnerer presentasjonene som er knyttet til et sted.
37          * 
38          * @param kilde Hva er prosjektets kilde? F.eks. NFR, EU
39          * @param prosjektId Prosjektets id.
40          * @param fraAr Inkluder kun arbeider med årstall >= fraAr
41      * @param tilAr Inkluder kun arbeider med årstall <= tilAr
42          * @param sortering sorteringsangivelse, se bruker-doc.
43          * @param format "xml" eller "json" for å angi output format
44          * @return en liste med vitenskapelige arbeider
45          * 
46          * @see http://localhost:8080/ws/hentArbeiderForProsjekt?kilde=NFR&prosjektnr=191195/v30&kategori=FOREDRAG&kategori=ARTIKKEL&sortering=HOVEDKAT_UNDERKAT_AAR
47      * @see http://localhost:8080/ws/hentArbeiderForProsjekt?kilde=NFR&prosjektnr=191195/v30&kategori=FOREDRAG&kategori=ARTIKKEL
48      * @see http://localhost:8080/ws/hentArbeiderForProsjekt?kilde=NFR&prosjektnr=191195/v30
49      * @see http://localhost:8080/ws/hentArbeiderForProsjekt?kilde=NFR 
50          */
51         @GET
52         @Cache(maxAge = 0)
53         public Response hentProsjektarbeid(
54                 @QueryParam("kilde") String kilde,
55                 @QueryParam("prosjektnr") String prosjektId,
56                         @QueryParam("fra") Short fraAr,
57                         @QueryParam("til") Short tilAr,
58                         @QueryParam("kategori") List<String> kategorier,
59                         @QueryParam("format") String format,
60                         @QueryParam("sortering") String sortering) {
61             
62             log.info("hentProsjektarbeid kilde: "+ kilde + ", prosjektid: " + prosjektId + ", fra: " + fraAr + ", til: " + tilAr);
63             
64             if (kategorier != null) {
65                 for (String kategori: kategorier) {
66                     log.info("hentProsjektarbeid kategori " + kategori);
67                 }               
68             }
69             
70                 if (format == null) {
71                         format = "xml";
72                 } else {
73                         format = format.toLowerCase();
74                 }
75
76                 if ((kilde == null)
77                                 || (!format.equals("xml") && !format.equals("json"))) {
78                         return Response.status(400).build();
79                 }
80                 
81                 String sql = "select va.varbeidlopenr, va.titteltekst_original, va.prosjekt, va.varbeidhovedkatkode, va.varbeidunderkatkode, va.arstall, "
82         + " vp.fornavn||' '||vp.etternavn navn, "
83         + " br.isbn, br.originaltittel, " // bok
84         + " ts.titteltekst, ts.issn, tp.sidenr_fra, tp.sidenr_til " // tidsskriftpublikasjon
85                 + " from vitenskapeligarbeid va" 
86                 + " inner join presentasjon_varbeid pv on pv.varbeidlopenr = va.varbeidlopenr "
87                 + " inner join presentasjon_kilde pk on pk.presentasjonslopenr = pv.presentasjonslopenr "
88                 + " inner join varbeid_person vp on vp.varbeidlopenr = va.varbeidlopenr "
89                 + " left outer join bok_rapport br on br.varbeidlopenr = va.varbeidlopenr "
90         + " left outer join tidsskriftpublikasjon tp on tp.varbeidlopenr = va.varbeidlopenr "
91                 + " left outer join tidsskrift ts on ts.tidsskriftnr = tp.tidsskriftnr"
92                 + " where pk.kildekode=? ";
93                 
94                 // FIXME hent tittel på bok/artikkelsamling/tidsskrift
95                 // ISBN
96                 
97                 if (prosjektId != null) {
98                     log.info("hentProsjektArbeid legger til prosjektkrav " + prosjektId);
99                     sql+= " and va.prosjekt = ? ";
100                 } else {
101                     log.info("hentProsjektArbeid legger ikke til prosjektkrav " + prosjektId);
102                 }
103                 
104                 if (fraAr != null) {
105                     sql += " and pv.arstall >= ? ";
106                 }
107         if (tilAr != null) {
108             sql += " and pv.arstall <= ? ";
109         }
110         
111         if (kategorier != null && !kategorier.isEmpty()) {
112             StringBuilder katparams = new StringBuilder("(");
113             for (int i = 0; i < kategorier.size() - 1; i++) {
114                 katparams.append("?,");
115             }
116             katparams.append("?)");
117             log.info("hentProsjektarbeid katparams bygd: " + katparams);
118             sql += " and (va.varbeidhovedkatkode in "+katparams +" or va.varbeidunderkatkode in " +katparams + ")";
119         }
120         
121         if (sortering != null) {
122             String sortpred = lagSortering(sortering);
123             if (sortpred == null) {
124                 return Response.status(400).build();
125             }
126             sql += " ORDER BY " + sortpred + " ";
127         }
128
129         StringBuilder output = new StringBuilder(4000);
130         MediaType outputFormat = MediaType.APPLICATION_XML_TYPE;
131         if (format.equals("json")) {
132             outputFormat = MediaType.APPLICATION_JSON_TYPE;
133         }
134         output.append("<prosjektarbeider>");
135         Connection conn = null;
136         Arbeider arbeider = new Arbeider();
137         try {
138             conn = Database.getConnection();
139             PreparedStatement stmt = conn.prepareStatement(sql);
140             log.info("hentProsjektArbeid() har conn for " + sql);
141             int index = 1;
142             stmt.setString(index++, kilde);
143             if (prosjektId != null) {
144                 stmt.setString(index++, prosjektId);
145             }
146             if (fraAr != null) {
147                 stmt.setShort(index++, fraAr);
148             }
149             if (tilAr != null) {
150                 stmt.setShort(index++, tilAr);
151             }
152             if (kategorier != null && !kategorier.isEmpty()) {
153                 for (String kategori : kategorier) { // hovedkat
154                     stmt.setString(index++, kategori);
155                 }
156                 for (String kategori : kategorier) { // underkat
157                     stmt.setString(index++, kategori);
158                 }
159             }
160             log.info("hentProsjektArbeid() " + sql + ", parametre: " + index);
161             ResultSet rs = stmt.executeQuery();
162             int results = 0;
163             while (rs.next()) {
164                 results++;
165
166                 arbeider.leggTilEllerOppdaterArbeid(rs.getInt(1),
167                         rs.getString(2), 
168                         rs.getString(3),
169                         kilde,
170                         rs.getString(4),
171                         rs.getString(5),
172                         rs.getInt(6),
173                         rs.getString(7),
174                         rs.getString(8),
175                         rs.getString(9),
176                         rs.getString(10),
177                         rs.getString(11),
178                         rs.getString(12),
179                         rs.getString(13));
180             }
181             log.info("hentProsjektArbeid return count" + results + ", arbeider " + arbeider.size());
182
183         } catch (SQLException e) {
184             Database.loggFeil(e);
185         } finally {
186             try {
187                 if (conn != null) conn.close();
188             } catch (SQLException e) {
189                 Database.loggFeil(e);
190
191             }
192         }
193
194
195         
196         
197         // til slutt, begrens antall: (dette maa gjoeres sist)
198         // FEILSITUASJON - returnerer 413 uansett om det er for mange
199         // sql = "select tekst_xml from (" + sql + ") where ROWNUM <= 1001";
200
201
202         return Response
203                 .status(200)
204                 .entity(arbeider.toXml())
205                 .variant(new Variant(outputFormat, new java.util.Locale("no_NO"), null)).build();
206
207
208         }
209
210         private String lagSortering(String sortering) {
211         String mapping[][] = { 
212                 { "HOVEDKAT_UNDERKAT_AAR", "varbeidhovedkatkode asc, varbeidunderkatkode asc, arstall desc"}
213                 };
214         for (int i = 0; i < mapping.length ; i++) {
215             if (mapping[i][0].equals(sortering)) return mapping[i][1];
216         }
217         return null;
218     }
219
220     private static String escapeXML(String input) {
221             return input.replace("&", "&amp;");
222         }
223
224     final private class Arbeider {
225         Hashtable<Integer,Arbeid> arbeider = new Hashtable<Integer,Arbeid>();
226         List<Integer> sortertenokler = new ArrayList<Integer>();
227         void leggTilEllerOppdaterArbeid(int arbeidnr, String prosjektId, String kilde, String tittel,
228                 String hovedkat, String underkat, int arstall, String forfatter, String isbn, String bokTittel, String tidsskriftTittel, String issn, String startside, String sluttside) {
229             if (arbeider.containsKey(arbeidnr)) {
230                 arbeider.get(arbeidnr).oppdater(forfatter);
231             } else {
232                 Arbeid arbeid = null;
233                 if (Arbeid.arbeidtype.BOK.toString().equals(hovedkat)) {
234                     arbeid = new Bok(arbeidnr,prosjektId,kilde,tittel,hovedkat,underkat,arstall, isbn, bokTittel);
235                 } else if (Arbeid.arbeidtype.TIDSSKRIFTPUBL.toString().equals(hovedkat)) {
236                     arbeid = new TidsskriftPublikasjon(arbeidnr,prosjektId,kilde,tittel,hovedkat,underkat,arstall,tidsskriftTittel, issn, startside, sluttside);
237                 } else {
238                     arbeid = new Arbeid(arbeidnr,prosjektId,kilde,tittel,hovedkat,underkat,arstall);
239                 }
240                 arbeid.oppdater(forfatter);
241                 arbeider.put(arbeidnr, arbeid);
242                 sortertenokler.add(arbeidnr);
243             }
244         }
245         String toXml() {
246             StringBuilder sb = new StringBuilder(4000);
247             sb.append("<prosjektarbeider>");
248             for (Integer nokkel : sortertenokler) {
249                 arbeider.get(nokkel).toXml(sb);
250             }
251             sb.append("</prosjektarbeider>");
252             return sb.toString();
253         }
254         int size() {
255             return sortertenokler.size();
256         }
257     }
258     protected static class Arbeid {
259         enum arbeidtype {
260             TIDSSKRIFTPUBL,BOK
261         }
262
263         int arbeidnr;
264         String prosjektId;
265         String kilde;
266         String tittel;
267         String hovedkat;
268         String underkat;
269         int arstall;
270         List<String> forfattere = new ArrayList<String>();
271         arbeidtype type;
272
273         Arbeid(int arbeidnr, String tittel, String prosjektId, String kilde, String hovedkat, String underkat, int arstall) {
274             log.info("Arbeid " + arbeidnr);
275             this.arbeidnr = arbeidnr;
276             this.prosjektId = prosjektId;
277             this.kilde = kilde;
278             this.tittel = tittel;
279             this.hovedkat = hovedkat;
280             this.underkat = underkat;
281             this.arstall = arstall;
282
283             if ("TIDSSKRIFTPUBL".equals(hovedkat)) {
284                 type = arbeidtype.TIDSSKRIFTPUBL;
285             } else if ("BOK".equals(hovedkat)) {
286                 type = arbeidtype.BOK;
287             }
288         }
289
290         void toXml(StringBuilder sb) {
291             sb.append("<arbeid>");
292             sb.append("<lopenr>" + arbeidnr+ "</lopenr>");
293             sb.append("<tittel>" + escapeXML(tittel)+ "</tittel>");
294             sb.append("<prosjektnr>" + prosjektId+ "</prosjektnr>");
295             sb.append("<kilde>" + kilde+ "</kilde>");
296             if (hovedkat != null) { sb.append("<hovedkat>" + hovedkat+ "</hovedkat>"); }
297             if (underkat != null) { sb.append("<underkat>" + underkat+ "</underkat>"); }
298             sb.append("<arstall>" + arstall+ "</arstall>");
299             if (type != null) {
300                 sb.append(getArbeidsTypeXml());
301             }
302             sb.append("<forfattere>");
303             for (String forfatter : forfattere) {
304                 sb.append("<forfatter>"+forfatter+"</forfatter>");
305             }
306             sb.append("</forfattere>");
307             sb.append("</arbeid>");
308         }
309
310         String getArbeidsTypeXml() {
311             return "";
312         }
313
314         void oppdater(String forfatter) {
315             log.info("oppdater " + forfatter);
316             forfattere.add(forfatter);
317         }
318     }
319     private static class Bok extends Arbeid {
320
321         String isbn;
322         private String bokTittel;
323
324         Bok(int arbeidnr, String tittel, String prosjektId, String kilde,
325                 String hovedkat, String underkat, int arstall, String isbn, String bokTittel) {
326             super(arbeidnr, tittel, prosjektId, kilde, hovedkat, underkat, arstall);
327             this.isbn = isbn;
328             this.bokTittel = bokTittel;
329         }
330         @Override
331         String getArbeidsTypeXml() {
332             final StringBuilder sb = new StringBuilder("<bok>");
333             if (isbn != null) {
334                 sb.append("<isbn>"+isbn+"</isbn>");
335             }
336             if (bokTittel != null) {
337                 sb.append("<tittel>" + bokTittel + "</tittel>");
338             }
339             sb.append("</bok>");
340             return sb.toString();
341         }
342     }
343     private static class TidsskriftPublikasjon extends Arbeid {
344         String tidsskriftTittel;
345         String issn;
346         String startside;
347         String sluttside;
348         public TidsskriftPublikasjon(int arbeidnr, String tittel, String prosjektId, String kilde,
349                 String hovedkat, String underkat, int arstall,
350                 String tidsskriftTittel, String issn, String startside, String sluttside) {
351             super(arbeidnr, tittel, prosjektId, kilde, hovedkat, underkat, arstall);
352             this.issn = issn;
353             this.tidsskriftTittel = tidsskriftTittel;
354             this.startside = startside;
355             this.sluttside = sluttside;
356         }
357         @Override
358         String getArbeidsTypeXml() {
359             final StringBuilder sb = new StringBuilder("<tidsskrift>");
360             sb.append("<tittel>"+ tidsskriftTittel +"</tittel>");
361             if (issn != null) sb.append("<issn>"+ issn +"</issn>");
362             if (startside != null) sb.append("<startside>"+ startside +"</startside>");
363             if (sluttside != null) sb.append("<sluttside>"+ sluttside +"</sluttside>");
364             sb.append("</tidsskrift>");
365             return sb.toString();
366         }
367
368     }
369 }