1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.mycore.mets.servlets;
20
21 import java.io.IOException;
22 import java.nio.file.Files;
23 import java.util.Collection;
24 import java.util.Locale;
25
26 import org.apache.logging.log4j.LogManager;
27 import org.apache.logging.log4j.Logger;
28 import org.jdom2.Document;
29 import org.mycore.common.MCRSession;
30 import org.mycore.common.MCRSessionMgr;
31 import org.mycore.common.MCRTransactionHelper;
32 import org.mycore.common.config.MCRConfiguration2;
33 import org.mycore.common.content.MCRContent;
34 import org.mycore.common.content.MCRJDOMContent;
35 import org.mycore.common.content.MCRPathContent;
36 import org.mycore.common.xml.MCRLayoutService;
37 import org.mycore.datamodel.common.MCRLinkTableManager;
38 import org.mycore.datamodel.metadata.MCRDerivate;
39 import org.mycore.datamodel.metadata.MCRMetadataManager;
40 import org.mycore.datamodel.metadata.MCRObjectID;
41 import org.mycore.datamodel.niofs.MCRPath;
42 import org.mycore.frontend.MCRFrontendUtil;
43 import org.mycore.frontend.servlets.MCRServlet;
44 import org.mycore.frontend.servlets.MCRServletJob;
45 import org.mycore.mets.model.MCRMETSGeneratorFactory;
46 import org.mycore.mets.tools.MCRMetsSave;
47
48 import jakarta.servlet.ServletException;
49 import jakarta.servlet.http.HttpServletRequest;
50 import jakarta.servlet.http.HttpServletResponse;
51
52
53
54
55 public class MCRMETSServlet extends MCRServlet {
56
57 private static final long serialVersionUID = 1L;
58
59 private static final Logger LOGGER = LogManager.getLogger(MCRMETSServlet.class);
60
61 public static final boolean STORE_METS_ON_GENERATE = MCRConfiguration2
62 .getOrThrow("MCR.Mets.storeMetsOnGenerate", Boolean::parseBoolean);
63
64 private boolean useExpire;
65
66 private static int CACHE_TIME;
67
68 @Override
69 protected void doGetPost(MCRServletJob job) throws Exception {
70 HttpServletRequest request = job.getRequest();
71 HttpServletResponse response = job.getResponse();
72 LOGGER.info(request.getPathInfo());
73
74 String derivate = getOwnerID(request.getPathInfo());
75 MCRPath rootPath = MCRPath.getPath(derivate, "/");
76
77 if (!Files.isDirectory(rootPath)) {
78 response.sendError(HttpServletResponse.SC_NOT_FOUND,
79 String.format(Locale.ENGLISH, "Derivate %s does not exist.", derivate));
80 return;
81 }
82 request.setAttribute("XSL.derivateID", derivate);
83 Collection<String> linkList = MCRLinkTableManager.instance().getSourceOf(derivate);
84 if (linkList.isEmpty()) {
85 MCRDerivate derivate2 = MCRMetadataManager.retrieveMCRDerivate(MCRObjectID.getInstance(derivate));
86 MCRObjectID ownerID = derivate2.getOwnerID();
87 if (ownerID != null && ownerID.toString().length() != 0) {
88 linkList.add(ownerID.toString());
89 } else {
90 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
91 String.format(Locale.ENGLISH,
92 "Derivate %s is not linked with a MCRObject. Please contact an administrator.", derivate));
93 return;
94 }
95 }
96 request.setAttribute("XSL.objectID", linkList.iterator().next());
97 response.setContentType("text/xml");
98
99 long lastModified = Files.getLastModifiedTime(rootPath).toMillis();
100
101 MCRFrontendUtil.writeCacheHeaders(response, CACHE_TIME, lastModified, useExpire);
102 long start = System.currentTimeMillis();
103 MCRContent metsContent = getMetsSource(job, useExistingMets(request), derivate);
104 MCRLayoutService.instance().doLayout(request, response, metsContent);
105 LOGGER.info("Generation of code by {} took {} ms", this.getClass().getSimpleName(),
106 System.currentTimeMillis() - start);
107 }
108
109
110
111
112 static MCRContent getMetsSource(MCRServletJob job, boolean useExistingMets, String derivate) throws Exception {
113 MCRPath metsPath = MCRPath.getPath(derivate, "/mets.xml");
114
115 try {
116 job.getRequest().setAttribute("XSL.derivateID", derivate);
117 String objectid = MCRLinkTableManager.instance().getSourceOf(derivate).iterator().next();
118
119 if (objectid == null || objectid.length() == 0) {
120 MCRDerivate derObj = MCRMetadataManager.retrieveMCRDerivate(MCRObjectID.getInstance(derivate));
121 MCRObjectID ownerID = derObj.getOwnerID();
122 objectid = ownerID.toString();
123 }
124
125 job.getRequest().setAttribute("XSL.objectID", objectid);
126 } catch (Exception x) {
127 LOGGER.warn("Unable to set \"XSL.objectID\" attribute to current request", x);
128 }
129
130 boolean metsExists = Files.exists(metsPath);
131 if (metsExists && useExistingMets) {
132 MCRContent content = new MCRPathContent(metsPath);
133 content.setDocType("mets");
134 return content;
135 } else {
136 Document mets = MCRMETSGeneratorFactory.create(MCRPath.getPath(derivate, "/")).generate().asDocument();
137 if (!metsExists && STORE_METS_ON_GENERATE) {
138 MCRMetsSave.saveMets(mets, MCRObjectID.getInstance(derivate));
139 }
140 return new MCRJDOMContent(mets);
141 }
142 }
143
144
145
146
147
148
149 @Override
150 public void init() throws ServletException {
151 super.init();
152 String cacheParam = getInitParameter("cacheTime");
153
154 CACHE_TIME = cacheParam != null ? Integer.parseInt(cacheParam) : (60 * 60 * 24);
155 useExpire = MCRConfiguration2.getBoolean("MCR.Component.MetsMods.Servlet.UseExpire").orElse(true);
156 }
157
158 private boolean useExistingMets(HttpServletRequest request) {
159 String useExistingMetsParam = request.getParameter("useExistingMets");
160 if (useExistingMetsParam == null) {
161 return true;
162 }
163 return Boolean.valueOf(useExistingMetsParam);
164 }
165
166 public static String getOwnerID(String pathInfo) {
167 StringBuilder ownerID = new StringBuilder(pathInfo.length());
168 boolean running = true;
169 for (int i = (pathInfo.charAt(0) == '/') ? 1 : 0; (i < pathInfo.length() && running); i++) {
170 switch (pathInfo.charAt(i)) {
171 case '/':
172 running = false;
173 break;
174 default:
175 ownerID.append(pathInfo.charAt(i));
176 break;
177 }
178 }
179 return ownerID.toString();
180 }
181
182
183
184
185
186
187
188
189 @Override
190 protected long getLastModified(HttpServletRequest request) {
191 String ownerID = getOwnerID(request.getPathInfo());
192 MCRSessionMgr.unlock();
193 MCRSession session = MCRSessionMgr.getCurrentSession();
194 MCRPath metsPath = MCRPath.getPath(ownerID, "/mets.xml");
195 try {
196 MCRTransactionHelper.beginTransaction();
197 try {
198 if (Files.exists(metsPath)) {
199 return Files.getLastModifiedTime(metsPath).toMillis();
200 } else if (Files.isDirectory(metsPath.getParent())) {
201 return Files.getLastModifiedTime(metsPath.getParent()).toMillis();
202 }
203 } catch (IOException e) {
204 LOGGER.warn("Error while retrieving last modified information from {}", metsPath, e);
205 }
206 return -1L;
207 } finally {
208 MCRTransactionHelper.commitTransaction();
209 MCRSessionMgr.releaseCurrentSession();
210 session.close();
211 }
212 }
213
214 }