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

org.omnifaces.resourcehandler.CombinedResourceInputStream Maven / Gradle / Ivy

There is a newer version: 4.5.1
Show newest version
/*
 * Copyright OmniFaces
 *
 * Licensed 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
 *
 *     https://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.omnifaces.resourcehandler;

import static java.util.logging.Level.FINE;
import static org.omnifaces.util.Faces.getRequestDomainURL;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.faces.application.Resource;

import org.omnifaces.util.Utils;

/**
 * 

* This {@link InputStream} implementation takes care that all in the constructor given resources are been read in * sequence. * * @author Bauke Scholtz */ public final class CombinedResourceInputStream extends InputStream { // Constants ------------------------------------------------------------------------------------------------------ private static final Logger logger = Logger.getLogger(CombinedResourceInputStream.class.getName()); private static final byte[] CRLF = { '\r', '\n' }; // Properties ----------------------------------------------------------------------------------------------------- private List streams; private Iterator streamIterator; private InputStream currentStream; // Constructors --------------------------------------------------------------------------------------------------- /** * Creates an instance of {@link CombinedResourceInputStream} based on the given resources. For each resource, the * {@link InputStream} will be obtained and hold in an iterable collection. * @param resources The resources to be read. * @throws IOException If something fails at I/O level. */ public CombinedResourceInputStream(Set resources) throws IOException { streams = new ArrayList<>(); String domainURL = getRequestDomainURL(); for (Resource resource : resources) { InputStream stream; try { stream = resource.getInputStream(); } catch (Exception richFacesDoesNotSupportThis) { logger.log(FINE, "Ignoring thrown exception; this can only be caused by a buggy component library.", richFacesDoesNotSupportThis); stream = new URL(domainURL + resource.getRequestPath()).openStream(); } streams.add(stream); streams.add(new ByteArrayInputStream(CRLF)); } streamIterator = streams.iterator(); if (streamIterator.hasNext()) { currentStream = streamIterator.next(); } } // Actions -------------------------------------------------------------------------------------------------------- /** * For each resource, read until its {@link InputStream#read()} returns -1 and then iterate to the * {@link InputStream} of the next resource, if any available, else return -1. */ @Override public int read() throws IOException { int read; while ((read = currentStream.read()) == -1) { if (streamIterator.hasNext()) { currentStream = streamIterator.next(); } else { break; } } return read; } /** * For each resource, read until its {@link InputStream#read()} returns -1 and then iterate to the * {@link InputStream} of the next resource, if any available, else return -1. */ @Override public int read(byte[] b, int offset, int length) throws IOException { int read; while ((read = currentStream.read(b, offset, length)) == -1) { if (streamIterator.hasNext()) { currentStream = streamIterator.next(); } else { break; } } return read; } /** * Closes the {@link InputStream} of each resource. Whenever the {@link InputStream#close()} throws an * {@link IOException} for the first time, it will be caught and be thrown after all resources have been closed. * Any {@link IOException} which is thrown by a subsequent close will be ignored by design. */ @Override public void close() throws IOException { IOException caught = null; for (InputStream stream : streams) { IOException e = Utils.close(stream); if (caught == null) { caught = e; // Don't throw it yet. We have to continue closing all other streams. } } if (caught != null) { throw caught; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy