View Javadoc
1   package org.exoplatform.services.wcm.extensions.scheduler.impl;
2   
3   import java.io.BufferedReader;
4   import java.io.ByteArrayOutputStream;
5   import java.io.File;
6   import java.io.FileOutputStream;
7   import java.io.FileReader;
8   import java.io.InputStreamReader;
9   import java.io.OutputStream;
10  import java.net.ConnectException;
11  import java.net.HttpURLConnection;
12  import java.net.URI;
13  import java.net.URL;
14  import java.sql.Timestamp;
15  import java.util.Calendar;
16  import java.util.Date;
17  import java.util.HashMap;
18  import java.util.List;
19  
20  import javax.jcr.Node;
21  import javax.jcr.NodeIterator;
22  import javax.jcr.RepositoryException;
23  import javax.jcr.Session;
24  import javax.jcr.query.Query;
25  import javax.jcr.query.QueryManager;
26  import javax.jcr.query.QueryResult;
27  import javax.xml.stream.XMLOutputFactory;
28  import javax.xml.stream.XMLStreamWriter;
29  
30  import org.exoplatform.services.cms.taxonomy.TaxonomyService;
31  import org.exoplatform.services.ecm.publication.PublicationPlugin;
32  import org.exoplatform.services.ecm.publication.PublicationService;
33  import org.exoplatform.services.jcr.RepositoryService;
34  import org.exoplatform.services.jcr.core.ManageableRepository;
35  import org.exoplatform.services.jcr.ext.common.SessionProvider;
36  import org.exoplatform.services.log.ExoLogger;
37  import org.exoplatform.services.log.Log;
38  import org.exoplatform.services.wcm.core.NodeLocation;
39  import org.exoplatform.services.wcm.extensions.publication.lifecycle.authoring.AuthoringPublicationConstant;
40  import org.exoplatform.services.wcm.extensions.security.SHAMessageDigester;
41  import org.exoplatform.services.wcm.utils.WCMCoreUtils;
42  import org.quartz.Job;
43  import org.quartz.JobDataMap;
44  import org.quartz.JobExecutionContext;
45  import org.quartz.JobExecutionException;
46  
47  /**
48   * Created by The eXo Platform MEA Author : haikel.thamri@exoplatform.com
49   */
50  public class ExportContentJob implements Job {
51    private static final Log LOG                  = ExoLogger.getLogger(ExportContentJob.class.getName());
52  
53    private static final String MIX_TARGET_PATH      = "mix:targetPath";
54  
55    private static final String MIX_TARGET_WORKSPACE = "mix:targetWorkspace";
56  
57    private static final String URL                  = "http://www.w3.org/2001/XMLSchema";
58  
59    private static final String START_TIME_PROPERTY  = "publication:startPublishedDate";
60  
61    private String fromState                         = null;
62  
63    private String toState                           = null;
64  
65    private String localTempDir                      = null;
66  
67    private String targetServerUrl                   = null;
68  
69    private String targetKey                         = null;
70  
71    private String predefinedPath                    = null;
72  
73    private String workspace                         = null;
74  
75    private String contentPath                       = null;
76  
77    public void execute(JobExecutionContext context) throws JobExecutionException {
78      Session session = null;
79      try {
80  
81        if (LOG.isInfoEnabled()) {
82          LOG.info("Start Execute ExportContentJob");
83        }
84        if (fromState == null) {
85  
86          JobDataMap jdatamap = context.getJobDetail().getJobDataMap();
87  
88          fromState = jdatamap.getString("fromState");
89          toState = jdatamap.getString("toState");
90          localTempDir = jdatamap.getString("localTempDir");
91          targetServerUrl = jdatamap.getString("targetServerUrl");
92          targetKey = jdatamap.getString("targetKey");
93          predefinedPath = jdatamap.getString("predefinedPath");
94          String[] pathTab = predefinedPath.split(":");
95          workspace = pathTab[1];
96          contentPath = pathTab[2];
97  
98          if (LOG.isDebugEnabled()) {
99            LOG.debug("Init parameters first time :");
100           LOG.debug("\tFromState = " + fromState);
101           LOG.debug("\tToState = " + toState);
102           LOG.debug("\tLocalTempDir = " + localTempDir);
103           LOG.debug("\tTargetServerUrl = " + targetServerUrl);
104         }
105       }
106       SessionProvider sessionProvider = SessionProvider.createSystemProvider();
107 
108       String containerName = WCMCoreUtils.getContainerNameFromJobContext(context);
109       RepositoryService repositoryService = WCMCoreUtils.getService(RepositoryService.class, containerName);
110       ManageableRepository manageableRepository = repositoryService.getCurrentRepository();
111       PublicationService publicationService = WCMCoreUtils.getService(PublicationService.class, containerName);
112       PublicationPlugin publicationPlugin = publicationService.getPublicationPlugins()
113                                                               .get(AuthoringPublicationConstant.LIFECYCLE_NAME);
114       session = sessionProvider.getSession(workspace, manageableRepository);
115       QueryManager queryManager = session.getWorkspace().getQueryManager();
116       boolean isExported = false;
117       Query query = queryManager.createQuery("select * from nt:base where publication:currentState='"
118                                                  + fromState
119                                                  + "' and jcr:path like '"
120                                                  + contentPath + "/%'",
121                                              Query.SQL);
122       File exportFolder = new File(localTempDir);
123       if (!exportFolder.exists())
124         exportFolder.mkdirs();
125       Date date = new Date();
126       long time = date.getTime();
127       File file = new File(localTempDir + File.separatorChar + time + ".xml");
128       ByteArrayOutputStream bos = null;
129       List<Node> categorySymLinks = null;
130       XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
131       FileOutputStream output = new FileOutputStream(file);
132       XMLStreamWriter xmlsw = outputFactory.createXMLStreamWriter(output, "UTF-8");
133       xmlsw.writeStartDocument("UTF-8", "1.0");
134       xmlsw.writeStartElement("xs", "contents", URL);
135       xmlsw.writeNamespace("xs", URL);
136       QueryResult queryResult = query.execute();
137       if (queryResult.getNodes().getSize() > 0) {
138         TaxonomyService taxonomyService = WCMCoreUtils.getService(TaxonomyService.class, containerName);
139         Date nodeDate = null;
140         Date now = null;
141         xmlsw.writeStartElement("xs", "published-contents", URL);
142         for (NodeIterator iter = queryResult.getNodes(); iter.hasNext();) {
143           Node node = iter.nextNode();
144           nodeDate = null;
145           if (node.hasProperty(START_TIME_PROPERTY)) {
146             now = Calendar.getInstance().getTime();
147             nodeDate = node.getProperty(START_TIME_PROPERTY).getDate().getTime();
148           }
149 
150           if (nodeDate == null || now.compareTo(nodeDate) >= 0) {
151             if (node.canAddMixin(MIX_TARGET_PATH))
152               node.addMixin(MIX_TARGET_PATH);
153             node.setProperty(MIX_TARGET_PATH, node.getPath());
154 
155             if (node.canAddMixin(MIX_TARGET_WORKSPACE))
156               node.addMixin(MIX_TARGET_WORKSPACE);
157             node.setProperty(MIX_TARGET_WORKSPACE, workspace);
158             node.save();
159             HashMap<String, String> context_ = new HashMap<>();
160             context_.put("containerName", containerName);
161             publicationPlugin.changeState(node, toState, context_);
162             if (LOG.isInfoEnabled()) {
163               LOG.info("change the status of the node " + node.getPath() + " to " + toState);
164             }
165             bos = new ByteArrayOutputStream();
166 
167             NodeLocation nodeLocation = NodeLocation.getNodeLocationByNode(node);
168             StringBuilder contenTargetPath = new StringBuilder();
169             contenTargetPath.append(nodeLocation.getRepository());
170             contenTargetPath.append(":");
171             contenTargetPath.append(nodeLocation.getWorkspace());
172             contenTargetPath.append(":");
173             contenTargetPath.append(nodeLocation.getPath());
174 
175             session.exportSystemView(node.getPath(), bos, false, false);
176             if (!isExported)
177               isExported = true;
178             xmlsw.writeStartElement("xs", "published-content", URL);
179             xmlsw.writeAttribute("targetPath", contenTargetPath.toString());
180             xmlsw.writeStartElement("xs", "data", URL);
181             xmlsw.writeCData(bos.toString());
182             xmlsw.writeEndElement();
183             xmlsw.writeStartElement("xs", "links", URL);
184 
185             categorySymLinks = taxonomyService.getAllCategories(node, true);
186 
187             for (Node nodeSymlink : categorySymLinks) {
188 
189               NodeLocation symlinkLocation = NodeLocation.getNodeLocationByNode(nodeSymlink);
190               StringBuilder symlinkTargetPath = new StringBuilder();
191               symlinkTargetPath.append(symlinkLocation.getRepository());
192               symlinkTargetPath.append(":");
193               symlinkTargetPath.append(symlinkLocation.getWorkspace());
194               symlinkTargetPath.append(":");
195               symlinkTargetPath.append(symlinkLocation.getPath());
196 
197               xmlsw.writeStartElement("xs", "link", URL);
198               xmlsw.writeStartElement("xs", "type", URL);
199               xmlsw.writeCharacters("exo:taxonomyLink");
200               xmlsw.writeEndElement();
201               xmlsw.writeStartElement("xs", "title", URL);
202               xmlsw.writeCharacters(node.getName());
203               xmlsw.writeEndElement();
204               xmlsw.writeStartElement("xs", "targetPath", URL);
205               xmlsw.writeCharacters(symlinkTargetPath.toString());
206               xmlsw.writeEndElement();
207               xmlsw.writeEndElement();
208             }
209             xmlsw.writeEndElement();
210             xmlsw.writeEndElement();
211           }
212         }
213         xmlsw.writeEndElement();
214       }
215       query = queryManager.createQuery("select * from nt:base where publication:currentState='unpublished' and jcr:path like '"
216                                            + contentPath + "/%'",
217                                        Query.SQL);
218       queryResult = query.execute();
219       if (queryResult.getNodes().getSize() > 0) {
220         xmlsw.writeStartElement("xs", "unpublished-contents", URL);
221         for (NodeIterator iter = queryResult.getNodes(); iter.hasNext();) {
222           Node node = iter.nextNode();
223 
224           if (node.isNodeType("nt:frozenNode"))
225             continue;
226           NodeLocation nodeLocation = NodeLocation.getNodeLocationByNode(node);
227           StringBuilder contenTargetPath = new StringBuilder();
228           contenTargetPath.append(nodeLocation.getRepository());
229           contenTargetPath.append(":");
230           contenTargetPath.append(nodeLocation.getWorkspace());
231           contenTargetPath.append(":");
232           contenTargetPath.append(nodeLocation.getPath());
233 
234           xmlsw.writeStartElement("xs", "unpublished-content", URL);
235           xmlsw.writeAttribute("targetPath", contenTargetPath.toString());
236           xmlsw.writeEndElement();
237           if (!isExported)
238             isExported = true;
239         }
240         xmlsw.writeEndElement();
241       }
242       xmlsw.writeEndElement();
243       if (bos != null) {
244         bos.close();
245       }
246       xmlsw.flush();
247       output.close();
248       xmlsw.close();
249       if (!isExported)
250         file.delete();
251       File[] files = exportFolder.listFiles();
252       if (files != null) {
253         for (int i = 0; i < files.length; i++) {
254           // connect
255           URI uri = new URI(targetServerUrl + "/copyfile/copy/");
256           URL url = uri.toURL();
257           HttpURLConnection connection = (HttpURLConnection) url.openConnection();
258 
259           // initialize the connection
260           connection.setDoOutput(true);
261           connection.setDoInput(true);
262           connection.setRequestMethod("POST");
263           connection.setUseCaches(false);
264           connection.setRequestProperty("Content-type", "text/plain");
265           connection.setRequestProperty("Connection", "Keep-Alive");
266 
267           OutputStream out = connection.getOutputStream();
268           BufferedReader reader = new BufferedReader(new FileReader(files[i].getPath()));
269           char[] buf = new char[1024];
270           int numRead = 0;
271           Date date_ = new Date();
272           Timestamp time_ = new Timestamp(date_.getTime());
273           String[] tab = targetKey.split("$TIMESTAMP");
274           StringBuilder resultKey = new StringBuilder();
275           for (int k = 0; k < tab.length; k++) {
276             resultKey.append(tab[k]);
277             if (k != (tab.length - 1))
278               resultKey.append(time_.toString());
279           }
280           String hashCode = SHAMessageDigester.getHash(resultKey.toString());
281           StringBuilder param = new StringBuilder();
282           param.append("timestamp=" + time_.toString() + "&&hashcode=" + hashCode
283               + "&&contentsfile=");
284           while ((numRead = reader.read(buf)) != -1) {
285             String readData = String.valueOf(buf, 0, numRead);
286             param.append(readData);
287           }
288           reader.close();
289           out.write(param.toString().getBytes());
290           out.flush();
291           connection.connect();
292           BufferedReader inStream = new BufferedReader(new InputStreamReader(connection.getInputStream()));
293           out.close();
294           String string = null;
295           while ((string = inStream.readLine()) != null) {
296             if (LOG.isDebugEnabled()) {
297               LOG.debug("The response of the production server:" + string);
298             }
299           }
300           connection.disconnect();
301           files[i].delete();
302         }
303       }
304 
305       if (LOG.isInfoEnabled()) {
306         LOG.info("End Execute ExportContentJob");
307       }
308     } catch (RepositoryException ex) {
309       if (LOG.isErrorEnabled()) {
310         LOG.error("Repository 'repository ' not found.", ex);
311       }
312     } catch (ConnectException ex) {
313       if (LOG.isErrorEnabled()) {
314         LOG.error("The front server is down.", ex);
315       }
316     } catch (Exception ex) {
317       if (LOG.isErrorEnabled()) {
318         LOG.error("Error when exporting content : ", ex);
319       }
320     } finally {
321       if (session != null)
322         session.logout();
323     }
324   }
325 }