Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 package org.apache.sling.samples.webloader.internal;
 
 import java.net.URL;
 import java.util.List;
 
 import javax.jcr.Item;
 import javax.jcr.Node;
 
A Webloader job, manages retrieval of documents from the web and storage in the Sling repository. This code is based on the "populate.jsp" example of the jackrabbit-webapp module.
  
 class WebloaderJob extends Thread implements WebloaderJobStatus {
     private Throwable error;
     private int numDocsLoaded;
     private final int maxDocsToRetrieve;
     private final int maxDocSize;
     private String statusInfo = "initialized";
     private String statusDetails = "";
     private boolean running = true;
     private final String jobId;
     private final String webQuery;
     private String storagePath;
     private final SlingRepository repository;
     private final MimeTypeService mimeTypeService;
     private Session session;
     private Node storageRoot;
     private static int idCounter;
     private final String [] filetypes;
     
     public static final String [] DEFAULT_FILETYPES = { "pdf""rtf""ppt""doc""xls" };
     public static final int URL_RETRIEVE_TIMEOUT_SECONDS = 10;
     
     private static final Logger log = LoggerFactory.getLogger(WebloaderJob.class);
     
     @SuppressWarnings("serial")
     static class DocTooBigException extends IOException {
         DocTooBigException(URL urlint size) {
             super("Document at URL " + url + " too big (" + size + " bytes), will be ignored");
         }
     }
     
     WebloaderJob(SlingRepository repositoryMimeTypeService mimeTypeService
             String webQueryString storagePathString fileExtensionsint maxDocsToRetrieveint maxDocSize) {
         synchronized (WebloaderJob.class) {
              = String.valueOf(++);
         }
         
         this. = repository;
         this. = mimeTypeService;
         this. = webQuery;
         this. = storagePath;
         this. = maxDocsToRetrieve;
         this. = maxDocSize;
         
         final String [] ft = fileExtensions == null ? null : fileExtensions.split(",");
         if(ft!=null && ft.length > 0) {
              = new String[ft.length];
             for(int i=0; i < ft.lengthi++) {
                [i] = ft[i].trim().toLowerCase();
            }
        } else {
             = ;
        }
        
        if(mimeTypeService == null) {
            throw new WebloaderException("Missing MimeTypeService");
        }
        if(repository == null) {
            throw new WebloaderException("Missing Repository");
        }
        
        setDaemon(true);
        start();
    }
    
    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer();
        for(String str : ) {
            if(sb.length() > 0) {
                sb.append(",");
            }
            sb.append(str);
        }
        
        return getClass().getSimpleName() + ", webQuery=" +  
            + ", storagePath=" + 
            + ", fileTypes=" + sb.toString()
            + ", maxDocsToRetrieve=" + 
            + ", maxDocSize=" + 
        ;
    }
    
    @Override
    public void run() {
        .debug("Job thread starting: {}"this);
        
        // TODO should use a session provided by client, but can we use it
        // safely for our async job?
         = null;
        
        if(.charAt(0) == '/') {
             = .substring(1);
        }
        final String absStoragePath = "/" + ;
        
        try {
             = .loginAdministrative(null);
            if(.itemExists(absStoragePath)) {
                final Item i = .getItem(absStoragePath);
                if(i.isNode()) {
                     = (Node)i;
                } else {
                    throw new WebloaderException("Item at " +  + " is not a Node");
                }
            } else {
                // TODO deep-create hierarchy if needed
                 = .getRootNode().addNode();
                .save();
            }
            
            int offset = 0;
            for(String type : ) {
                final URL[] urls = getDocumentUrlsFromGoogle(typeoffset);
                for(URL url : urls) {
                    try {
                        getAndStoreDocument(url);
                        .save();
                        ++;
                        if( >= ) {
                            break;
                        }
                    } catch(DocTooBigException dtb) {
                        .info(dtb.getMessage());
                    } catch(Exception e) {
                        .warn("Exception while retrieving url " + urle);
                    } finally {
                        .refresh(false);
                    }
                }
                offset += 10;
                
                if( >= ) {
                    break;
                }
            }
            
             = "All done.";
            
        } catch(Exception e) {
             = e;
            .warn("Exception in WebloaderJob.run()"e);
             = "Exception while running job: " + e;
            
        } finally {
            if( != null) {
                .logout();
            }
             = "";
             = false;
        }
        
        if( >= ) {
            .info("Stopped after retrieving maximum number of documents ({})");
        }
        
        .info("Job thread ends: {}, {} documents loaded"this);
    }
    
    private URL [] getDocumentUrlsFromGoogle(String currentFiletypeint startthrows IOExceptionBadLocationException {
        final List urls = new ArrayList();
        String query =  + " filetype:" + currentFiletype;
        final URL google = new URL("http://www.google.com/search?q=" +
                URLEncoder.encode(query"UTF-8") + "&start=" + start);
        .debug("Querying {}"google.toString());
         = "Querying " + google.toString();
         = "";
        URLConnection con = google.openConnection();
        con.setRequestProperty("User-Agent""");
        InputStream in = con.getInputStream();
        try {
            HTMLEditorKit kit = new HTMLEditorKit();
            HTMLDocument doc = new HTMLDocument();
            doc.putProperty("IgnoreCharsetDirective".);
            kit.read(new InputStreamReader(in"UTF-8"), doc, 0);
            HTMLDocument.Iterator it = doc.getIterator(..);
            while (it.isValid()) {
                if(it.getAttributes() != null) {
                    String href = (Stringit.getAttributes().getAttribute(..);
                    if (href != null && href.endsWith("." + currentFiletype)) {
                        URL url = new URL(new URL("http""www.google.com""dummy"), href);
                        if (url.getHost().indexOf("google") == -1) {
                            .debug("Got document URL from google: {}"url);
                             = "Got URL " + url;
                            urls.add(url);
                        }
                    }
                }
                it.next();
            }
        } finally {
            in.close();
        }
        return (URL[]) urls.toArray(new URL[urls.size()]);
    }
    
    private void getAndStoreDocument(URL currentURLthrows RepositoryExceptionIOException {
         = "Retrieving document " + currentURL;
         = "";
        
        // build JCR path for storing document, based on its URL
        String path = currentURL.getPath();
        if (path.startsWith("/")) {
            path = path.substring(1);
        }
        final String host = currentURL.getHost();
        final List folderNames = new ArrayList();
        folderNames.addAll(Arrays.asList(host.split("\\.")));
        Collections.reverse(folderNames);
        folderNames.addAll(Arrays.asList(path.split("/", 0)));
        final String filename = URLDecoder.decode((StringfolderNames.remove(folderNames.size() - 1), "UTF-8").replaceAll(":""_");
        Node node = ;
        for (Iterator fn = folderNames.iterator(); fn.hasNext(); ) {
            String name = URLDecoder.decode((Stringfn.next(), "UTF-8");
            name = name.replaceAll(":""_");
            if (name.length() == 0) {
                continue;
            }
            if (!node.hasNode(name)) {
                node.addNode(name"nt:folder");
            }
            node = node.getNode(name);
        }
        
        .debug("Retrieving document {}, will be stored at {}"currentURLnode.getPath() + "/" + filename);
        
        if (!node.hasNode(filename)) {
            Node file = node.addNode(filename"nt:file");
            final Node resource = file.addNode("jcr:content""nt:resource");
            getAndStoreContent(currentURLresourcefilename);
        }
    }
    
    private void getAndStoreContent(URL currentURLNode resourceString filename
    throws RepositoryExceptionIOException {
         = "Retrieving content from " + currentURL;
         = "";
        
        final URLConnection con = currentURL.openConnection();
        con.setReadTimeout( * 1000);
        InputStream in = con.getInputStream();
        try {
            // Read with a ProgressInputStream, so that our status is updated while
            // downloading
            int length = con.getContentLength();
            if (length != -1) {
                if(length >  * 1024) {
                    throw new DocTooBigException(currentURLlength);
                }
                in = new ProgressInputStream(inlength) {
                    int nextReport = 0;
                    protected void reportProgress(int bytesReadint totalBytesToRead) {
                        if(bytesRead > ) {
                             += 1024;
                             = "Downloaded " + bytesRead + " bytes out of " + totalBytesToRead;
                        }
                    }
                };
            }
            
            resource.setProperty("jcr:data"in);
            final String mimeType = .getMimeType(filename);
            resource.setProperty("jcr:mimeType"mimeType);
            final Calendar lastModified = Calendar.getInstance();
            lastModified.setTimeInMillis(con.getLastModified());
            resource.setProperty("jcr:lastModified"lastModified);
        } finally {
            if(in != null) {
                in.close();
            }
        }
    }
    
    String getJobId() {
        return ;
    }
    
    
    public Throwable getError() {
        return ;
    }

    
    public int getNumberOfDocumentsLoaded() {
        return ;
    }

    
    public String getStatusInfo() {
        return ;
    }

    
    public String getStatusDetails() {
        return ;
    }

    
    public boolean isRunning() {
        return ;
    }
New to GrepCode? Check out our FAQ X