All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.sommeri.less4j.LessSource Maven / Gradle / Ivy

Go to download

Less language is an extension of css and less4j compiles it into regular css. It adds several dynamic features into css: variables, expressions, nested rules. Less4j is a port. The original compiler was written in JavaScript and is called less.js. The less language is mostly defined in less.js documentation/issues and by what less.js actually do. Links to less.js: * home page: http://lesscss.org/ * source code & issues: https://github.com/cloudhead/less.js

There is a newer version: 1.17.2
Show newest version
package com.github.sommeri.less4j;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

import com.github.sommeri.less4j.utils.URIUtils;

public abstract class LessSource {

  public abstract LessSource relativeSource(String filename) throws FileNotFound, CannotReadFile, StringSourceException;

  public abstract String getContent() throws FileNotFound, CannotReadFile;

  public abstract byte[] getBytes() throws FileNotFound, CannotReadFile;

  /**
   * @return less source location uri or null. If non-null, last path part must be equal to whatever {@link #getName()} returns.
   * 
   */
  public URI getURI() {
    return null;
  }

  /**
   * Less source name. Can be anything if the {@link #getAbsoluteURI()} returns non null, otherwise last path part.
   */
  public String getName() {
    return null;
  }

  public abstract static class AbstractHierarchicalSource extends LessSource {

    protected AbstractHierarchicalSource parent;

    protected long lastModified;

    protected long latestModified;

    protected Collection importedSources;

    public AbstractHierarchicalSource() {
      super();

      importedSources = new ArrayList();
    }

    public AbstractHierarchicalSource(AbstractHierarchicalSource parent) {
      super();
      this.parent = parent;
    }

    protected void setLastModified(long lastModified) {
      this.lastModified = lastModified;
      setLatestModified(lastModified);
    }

    protected void addImportedSource(LessSource source) {
      if (parent != null) {
        parent.addImportedSource(source);
      } else {
        importedSources.add(source);
      }
    }

    public Collection getImportedSources() {
      return importedSources;
    }

    public long getLastModified() {
      return lastModified;
    }

    public long getLatestModified() {
      return latestModified;
    }

    public void setLatestModified(long latestModified) {
      this.latestModified = latestModified;
      if (parent != null && latestModified > parent.getLatestModified()) {
        parent.setLatestModified(latestModified);
      }
    }

  }

  public static class URLSource extends AbstractHierarchicalSource {

    private URL inputURL;
    private String charsetName;

    public URLSource(URL inputURL) {
      this(inputURL, null);
    }

    public URLSource(URL inputURL, String charsetName) {
      super();
      this.inputURL = inputURL;
      this.charsetName = charsetName;
    }

    public URLSource(URLSource parent, String filename) throws FileNotFound, CannotReadFile {
      this(parent, filename, null);
    }
    
    public URLSource(URLSource parent, String filename, String charsetName) throws FileNotFound, CannotReadFile {
      super(parent);
      try {
        this.inputURL = new URL(URIUtils.toParentURL(parent.inputURL), filename);
      } catch (MalformedURLException e) {
        throw new FileNotFound();
      }
      this.charsetName = charsetName;
      parent.addImportedSource(this);
    }

    @Override
    public String getContent() throws FileNotFound, CannotReadFile {
      try {
        URLConnection connection = getInputURL().openConnection();
        Reader input = charsetName != null ? new InputStreamReader(connection.getInputStream(), charsetName) : new InputStreamReader(connection.getInputStream());
        String content = IOUtils.toString(input).replace("\r\n", "\n");
        setLastModified(connection.getLastModified());
        input.close();
        return content;
      } catch (FileNotFoundException ex) {
        throw new FileNotFound();
      } catch (IOException ex) {
        throw new CannotReadFile();
      }

    }

    @Override
    public byte[] getBytes() throws FileNotFound, CannotReadFile {
      try {
        URLConnection connection = getInputURL().openConnection();
        Reader input = new InputStreamReader(connection.getInputStream());
        setLastModified(connection.getLastModified());
        byte[] content = IOUtils.toByteArray(input);
        input.close();
        return content;
      } catch (FileNotFoundException ex) {
        throw new FileNotFound();
      } catch (IOException ex) {
        throw new CannotReadFile();
      }

    }

    @Override
    public LessSource relativeSource(String filename) throws FileNotFound, CannotReadFile {
      return new URLSource(this, filename, charsetName);
    }

    public URL getInputURL() {
      return inputURL;
    }

    @Override
    public URI getURI() {
      try {
        return inputURL.toURI();
      } catch (URISyntaxException e) {
        return null;
      }
    }

    @Override
    public String getName() {
      return new File(inputURL.getPath()).getName();
    }

    public String toString() {
      return inputURL.toString();
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((inputURL == null) ? 0 : inputURL.hashCode());
      result = prime * result + ((charsetName == null) ? 0 : charsetName.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      URLSource other = (URLSource) obj;
      if (inputURL == null) {
        if (other.inputURL != null)
          return false;
      } else if (!inputURL.equals(other.inputURL))
        return false;
      if (charsetName == null) {
        if (other.charsetName != null)
          return false;
      } else if (!charsetName.equals(other.charsetName))
        return false;
      return true;
    }

  }

  public static class FileSource extends AbstractHierarchicalSource {

    private File inputFile;
    private String charsetName;

    public FileSource(File inputFile) {
      this(inputFile, null);
    }
    
    public FileSource(File inputFile, String charsetName) {
      this.inputFile = inputFile;
      this.charsetName = charsetName;
    }

    public FileSource(FileSource parent, String filename) {
      this(parent, filename, null);
    }
    
    public FileSource(FileSource parent, String filename, String charsetName) {
      super(parent);
      this.inputFile = new File(parent.inputFile.getParentFile(), filename);
      this.charsetName = charsetName;
      parent.addImportedSource(this);
    }

    @Override
    public URI getURI() {
      try {
        String path = inputFile.toString();
        path = URIUtils.convertPlatformSeparatorToUri(path);
        return new URI(path);
      } catch (URISyntaxException e) {
        return null;
      }
    }

    @Override
    public String getName() {
      return inputFile.getName();
    }

    @Override
    public String getContent() throws FileNotFound, CannotReadFile {
      try {
        Reader input;
        if (charsetName != null) {
          input = new InputStreamReader(new FileInputStream(inputFile), charsetName);
        } else {
          input = new FileReader(inputFile);
        }
        try {
          String content = IOUtils.toString(input).replace("\r\n", "\n");
          setLastModified(inputFile.lastModified());
          return content;
        } finally {
          input.close();
        }
      } catch (FileNotFoundException ex) {
        throw new FileNotFound();
      } catch (IOException ex) {
        throw new CannotReadFile();
      }
    }

    @Override
    public byte[] getBytes() throws FileNotFound, CannotReadFile {
      try {
        byte[] content = FileUtils.readFileToByteArray(inputFile);
        setLastModified(inputFile.lastModified());
        return content;
      } catch (FileNotFoundException ex) {
        throw new FileNotFound();
      } catch (IOException ex) {
        throw new CannotReadFile();
      }
    }

    @Override
    public FileSource relativeSource(String filename) {
      return new FileSource(this, filename);
    }

    public File getInputFile() {
      return inputFile;
    }

    public String toString() {
      return inputFile.toString();
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      File canonicalInputFile = getCanonicalFile();
      result = prime * result + ((canonicalInputFile == null) ? 0 : canonicalInputFile.hashCode());
      result = prime * result + ((charsetName == null) ? 0 : charsetName.hashCode());
      return result;
    }

    private File getCanonicalFile() {
      try {
        return inputFile.getCanonicalFile();
      } catch (IOException e) {
        return inputFile.getAbsoluteFile();
      }
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      FileSource other = (FileSource) obj;
      File absoluteInputFile = getCanonicalFile();
      if (absoluteInputFile == null) {
        if (other.inputFile != null)
          return false;
      } else if (!absoluteInputFile.equals(other.inputFile.getAbsoluteFile()))
        return false;
      if (charsetName == null) {
        if (other.charsetName != null)
          return false;
      } else if (!charsetName.equals(other.charsetName))
        return false;
      return true;
    }

  }

  public static class StringSource extends LessSource {

    private String content;
    private String name;
    private URI uri;

    public StringSource(String content) {
      this(content, null);
    }

    public StringSource(String content, String name) {
      this.content = content;
      this.name = name;
    }

    public StringSource(String content, String name, URI uri) {
      this.content = content;
      this.name = name;
      this.uri = uri;
    }

    @Override
    public URI getURI() {
      return uri;
    }

    @Override
    public String getName() {
      return name;
    }

    @Override
    public String getContent() {
      return content;
    }

    @Override
    public byte[] getBytes() {
      return content!=null?content.getBytes():null;
    }

    @Override
    public LessSource relativeSource(String filename) throws StringSourceException {
      throw new StringSourceException();
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((content == null) ? 0 : content.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj)
        return true;
      if (obj == null)
        return false;
      if (getClass() != obj.getClass())
        return false;
      StringSource other = (StringSource) obj;
      if (content == null) {
        if (other.content != null)
          return false;
      } else if (!content.equals(other.content))
        return false;
      return true;
    }

  }

  @SuppressWarnings("serial")
  public static class StringSourceException extends Exception {

  }

  @SuppressWarnings("serial")
  public static class FileNotFound extends Exception {

  }

  @SuppressWarnings("serial")
  public static class CannotReadFile extends Exception {

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy