]> git.uio.no Git - cristin-ws.git/blob - src/main/java/no/cristin/ws/FinnForskerId.java
join inn institusjon, hent presentasjonsnr mm
[cristin-ws.git] / src / main / java / no / cristin / ws / FinnForskerId.java
1 package no.cristin.ws;
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.Arrays;
9 import java.util.Hashtable;
10 import java.util.List;
11 import java.util.Map;
12
13 import javax.servlet.http.HttpServletRequest;
14 import javax.ws.rs.GET;
15 import javax.ws.rs.Path;
16 import javax.ws.rs.QueryParam;
17 import javax.ws.rs.core.Context;
18 import javax.ws.rs.core.HttpHeaders;
19 import javax.ws.rs.core.MediaType;
20 import javax.ws.rs.core.Response;
21 import javax.ws.rs.core.Response.Status;
22
23 import no.cristin.ws.exception.NotFoundException;
24 import no.cristin.ws.exception.TooManyException;
25
26 import org.jboss.resteasy.annotations.cache.Cache;
27 import org.json.JSONException;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * Person RPC-tjeneste.
33  */
34 @Path("/finnForsker")
35 public class FinnForskerId {
36
37         private static final Logger log = LoggerFactory.getLogger(FinnForskerId.class.toString());
38     @Context private HttpServletRequest servletRequest;
39
40     // NB! hardkoding av cristin-url som kjem til å forandre seg!
41     private static final String presURL = "http://www.cristin.no/as/WebObjects/cristin.woa/wa/personVis?type=PERSON&pnr=";
42
43         /**
44          * Returnerer liste av personer som har matchende navn og institusjon.
45          * 
46          * @param navn Forskerens navn
47          * @param institusjon Forskerens institusjon
48          * @param format
49          *            "html", "xml" eller "json" for å angi output format
50          * @return liste over forskere som matcher input
51          */
52         @GET
53         @Cache(maxAge = 0)
54         public Response finnForsker(
55                 @QueryParam("navn") String navn,
56                         @QueryParam("inst") String institusjon,
57                         @QueryParam("format") String format) throws JSONException {
58             log.info("finnForsker " + navn + ":" + institusjon + ":" + format);
59
60             List<String> errors = new ArrayList<String>();
61
62             if (format == null) format = "xml";
63         MediaType outputFormat = MediaType.APPLICATION_XML_TYPE;
64         switch (format) {
65             case "json":
66                 outputFormat = MediaType.APPLICATION_JSON_TYPE;
67                 break;
68             case "html":
69                 outputFormat = MediaType.TEXT_HTML_TYPE;
70                 break;
71             default:
72                 outputFormat = MediaType.APPLICATION_XML_TYPE;
73         }
74
75                 if (navn == null || institusjon == null) {
76                    return Response.status(Status.BAD_REQUEST).entity("navn eller inst er null").build();
77                 }
78
79                 String navnOracleMatchParams = "";
80                 if (!harStoreBokstaver(navn)) {
81                     navnOracleMatchParams = ", 'i'";
82                 }
83         navn = navn.trim();
84         institusjon = institusjon.trim().toLowerCase();
85
86         String sql = "select p.personlopenr as lopenr, p.presentasjonslopenr as presnr, p.fornavn ||' '|| p.etternavn as navn, "
87                 + "case when p.bilde is not null then 'J' else 'N' end as bilde, "
88                 + "i.institusjonsakronym as akronym, "
89                 + "i.institusjonsnavn_bokmal as instnavnb, i.institusjonsnavn_nynorsk as instnavnn, i.institusjonsnavn_engelsk as instnavne, "
90                 + "s.stednavn_bokmal as stednavnb, s.stednavn_nynorsk as stednavnn, s.stednavn_engelsk as stednavne "
91                 + "from frida.person p "
92                 + "left outer join frida.ansettelse a on a.personlopenr = p.personlopenr "
93                 + "left outer join frida.sted s on s.institusjonsnr = a.institusjonsnr and s.avdnr = a.avdnr and "
94                 + "                                 s.undavdnr = a.undavdnr and s.gruppenr = a.gruppenr "
95                 + "left outer join frida.institusjon i on i.institusjonsnr = s.institusjonsnr "
96             + " where p.fodselsdato is not null and p.personnr is not null and ";
97         List<String> parameters = new ArrayList<String>();
98         String[] splitnavn = navn.split(" ");
99         for (int i = 0; i < splitnavn.length; i++) {
100             if (splitnavn[i].isEmpty()) continue;
101
102             parameters.add(splitnavn[i].toLowerCase());
103             if (i < splitnavn.length - 1) 
104                 sql += "regexp_like(p.fornavn||' '||p.etternavn, ? "+navnOracleMatchParams+") and ";
105             else 
106                 sql += "regexp_like(p.fornavn||' '||p.etternavn, ? "+navnOracleMatchParams+") ";
107         }
108         
109         // FIXME legg til fornuftig institusjonssjekk
110 //        for (String s: institusjon.split(" ")) {
111 //            if (!s.isEmpty()) {
112 //                parameter.add("%" + s.toLowerCase() + "%");
113 //                sql += "(lower(s.stedakronym) like ? or ";
114 //            }
115 //        }
116
117         Forskere forskere = new Forskere();
118         try (
119                 Connection conn = Database.getConnection();
120                 PreparedStatement stmt = conn.prepareStatement(sql);
121                 ) {
122
123             int index = 1;
124             for (int idx = 1; idx <= parameters.size(); idx++) {
125                 log.info("finnForsker legger til param " + idx + ": " + parameters.get(idx - 1));
126                 stmt.setString(idx, parameters.get(idx - 1));
127             }
128             log.info("finnForsker " + sql + ", parametre: " + index);
129             ResultSet rs = stmt.executeQuery();
130             int results = 0;
131             final String bildeURL = servletRequest.getRequestURL().substring(0,servletRequest.getRequestURL().indexOf("finnFo"));
132             while (rs.next()) {
133                 forskere.leggTilEllerOppdater(
134                         rs.getInt("lopenr"),
135                         rs.getInt("presnr") == 0 ? null:  presURL + rs.getInt("presnr"),
136                         rs.getString("navn"),
137                         "N".equals(rs.getString("bilde")) ? null : bildeURL,
138                         rs.getString("akronym"),
139                         rs.getString("instnavnb"),
140                         rs.getString("instnavnn"),
141                         rs.getString("instnavne"),
142                         rs.getString("stednavnb"),
143                         rs.getString("stednavnn"),
144                         rs.getString("stednavne")
145                         );
146             }
147             
148         } catch (SQLException e) {
149             log.error("finnForsker error",e);
150         }
151             
152
153         
154         return Response
155                 .status(200)
156                 .entity(forskere.format(outputFormat))
157                 .header(HttpHeaders.CONTENT_TYPE, outputFormat+"; charset=UTF-8")
158                 .build();
159
160
161         }
162
163         private boolean harStoreBokstaver(String navn) {
164             for (int i = 0; i < navn.length(); i++) {
165                 if (navn.charAt(i) > 64 && navn.charAt(i) < 91) return true;
166             }
167         return false;
168     }
169
170     private static final String escapeXML(String input) {
171         return input.replace("&", "&amp;");
172     }
173
174     final private class Forskere {
175         Hashtable<Integer,Forsker> forskere = new Hashtable<Integer,Forsker>();
176         Object format(MediaType outputFormat) throws JSONException {
177             StringBuilder sb = new StringBuilder(4000);
178             sb.append("<forskere>");
179             for (Forsker f: forskere.values()) {
180                 f.toXml(sb);
181             }
182             sb.append("</forskere>");
183             if (outputFormat.equals(MediaType.APPLICATION_JSON_TYPE)) {
184                 String json = org.json.XML.toJSONObject(sb.toString()).toString();
185                 return json;
186             }
187             return sb.toString();
188         }
189         public void leggTilEllerOppdater(int lopenr, String presentasjonsURL, String navn,
190                 String bildeURL, String akronym,
191                 String instavnBokmål, String instavnNynorsk, String instavnEngelsk,
192                 String stednavnBokmål, String stednavnNynorsk, String stednavnEngelsk) {
193             Sted s = akronym == null ? null : new Sted(akronym, instavnBokmål, instavnNynorsk, instavnEngelsk, stednavnBokmål, stednavnNynorsk, stednavnEngelsk);
194             if (forskere.containsKey(lopenr)) {
195                 if (s != null) forskere.get(lopenr).tilhorigheter.add(s);
196             } else {
197                 Forsker f = new Forsker(lopenr, presentasjonsURL, navn, bildeURL);
198                 if (s != null) f.tilhorigheter.add(s);
199                 forskere.put(lopenr, f);
200             }
201             
202         }
203         
204     }
205         
206         final static private class Forsker {
207             private int lopenr;
208         private String presentasjonsURL;
209             private String navn;
210         private String bildeURL;
211             private List<Sted> tilhorigheter = new ArrayList<Sted>();
212
213             public Forsker (int lopenr, String presentasjonsURL, String navn, String bildeURL) {
214                 this.lopenr = lopenr;
215                 this.presentasjonsURL = presentasjonsURL;
216                 this.navn = navn;
217                 this.bildeURL = bildeURL;
218             }
219
220         public void toXml(StringBuilder sb) {
221             sb.append("<forsker ");
222             sb.append("id=\"");
223             sb.append(lopenr);
224             sb.append("\" navn=\"");
225             sb.append(navn);
226             sb.append("\" ");
227             if (presentasjonsURL != null) {
228                 sb.append("presentasjon=\"");
229                 sb.append(escapeXML(presentasjonsURL));
230                 sb.append(lopenr);
231                 sb.append("\" ");                
232             }
233             if (bildeURL != null) {
234                 sb.append("bilde=\"");
235                 sb.append(bildeURL);
236                 sb.append("hentPersonBilde?lopenr=");
237                 sb.append(lopenr);
238                 sb.append("\"");
239             }
240             sb.append(">");
241             for (Sted s: tilhorigheter) {
242                 s.toXml(sb);
243             }
244             sb.append("</forsker>");
245         }
246
247         }
248         final static private class Sted {
249             private String akronym;
250         private String instnavnBokmål;
251         private String instnavnNynorsk;
252         private String instnavnEngelsk;
253         private String stednavnBokmål;
254         private String stednavnNynorsk;
255         private String stednavnEngelsk;
256
257         public Sted(String akronym, String instnavnBokmål, String instnavnNynorsk, String instnavnEngelsk,
258                 String navnBokmål, String navnNynorsk, String navnEngelsk) {
259                 this.akronym = akronym;
260             this.instnavnBokmål = instnavnBokmål;
261             this.instnavnNynorsk = instnavnNynorsk;
262             this.instnavnEngelsk = instnavnEngelsk;
263                 this.stednavnBokmål = navnBokmål;
264                 this.stednavnNynorsk = navnNynorsk;
265                 this.stednavnEngelsk = navnEngelsk;
266             }
267
268         public void toXml(StringBuilder sb) {
269             sb.append("<sted akronym=\"");
270             sb.append(escapeXML(akronym));
271             sb.append("\" ");
272             sb.append("instnavnb=\"");
273             sb.append(escapeXML(instnavnBokmål));
274             sb.append("\" ");
275             if (instnavnNynorsk != null) sb.append(" instnavnn=\"" + escapeXML(instnavnNynorsk) + "\" ");
276             if (instnavnEngelsk != null) sb.append(" instnavne=\"" + escapeXML(instnavnEngelsk) + "\" ");
277             sb.append("stednavnb=\"");
278             sb.append(escapeXML(stednavnBokmål));
279             sb.append("\" ");
280             if (stednavnNynorsk != null) sb.append(" stednavnn=\"" + escapeXML(stednavnNynorsk) + "\" ");
281             if (stednavnEngelsk != null) sb.append(" stednavne=\"" + escapeXML(stednavnEngelsk) + "\" ");
282             
283             sb.append("/>");
284         }
285         }
286         
287 }
288