/* * Copyright 2012 Joseph Spencer. * * 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 * * 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 com.spencernetdevelopment; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * This class manages GroupedAssetTransaction[s]. It ensured that a transaction * is only built once within it's session. * * @author Joseph Spencer */ public class GroupedAssetTransactionManager { private final AssetManager assetManager; private final AssetResolver assetResolver; private final List<GroupedAssetTransaction> transactions = new ArrayList<>(); private final Set<String> processedItems = new HashSet<>(); private final StaticPagesConfiguration config; private final FileUtils fileUtils; public GroupedAssetTransactionManager( AssetManager assetManager, AssetResolver assetResolver, StaticPagesConfiguration config, FileUtils fileUtils ) throws IllegalArgumentException { if(assetManager == null){ throw new IllegalArgumentException("assetManager was null"); } if(assetResolver == null){ throw new IllegalArgumentException("assetResolver was null"); } if(config == null){ throw new IllegalArgumentException("config was null"); } if(fileUtils == null){ throw new IllegalArgumentException("fileUtils was null"); } this.assetManager=assetManager; this.assetResolver=assetResolver; this.config=config; this.fileUtils=fileUtils; } /** * Processes the transactions currently waiting to be processed and outputs * the contents of the processed asset to disk. * * @return * @throws IOException See the following methods:<br/> * {@link AssetManager#getJS(java.lang.String, boolean)}<br/> * {@link AssetManager#getCSS(java.lang.String, boolean)}<br/> */ public List<GroupedAssetTask<Object>> getGroupedAssetTasks() throws IOException, IllegalArgumentException, URISyntaxException { List<GroupedAssetTask<Object>> tasks = new ArrayList(); List<GroupedAssetTransaction> transactionsToConsider=new ArrayList<>(); synchronized(transactions){ if(transactions.size()<1){ return tasks; } for(GroupedAssetTransaction transaction:transactions){ if(transaction.isClosed()){ transactionsToConsider.add(transaction); } } for(GroupedAssetTransaction transaction:transactionsToConsider){ transactions.remove(transaction); } } for(GroupedAssetTransaction transaction:transactionsToConsider){ String identifier = transaction.getIdentifier(); String type = transaction.getType(); switch(type){ case "js": identifier = assetResolver.getJSPath(identifier); break; case "css": identifier = assetResolver.getCSSPath(identifier); break; } synchronized(processedItems){ if(processedItems.contains(identifier)){ continue; } else { processedItems.add(identifier); } } FilePath proposedFilePath=config.getBuildDirPath().resolve(identifier); /* * Here we see if any of the transactions have a file that is in fact * newer than the target file under build. If there isn't a newer * file, then we can skip this transaction. */ if(proposedFilePath.toFile().isFile()){ FilePath assetDirPath = config.getAssetsDirPath(); File proposedFile = proposedFilePath.toFile(); long lastModified = proposedFile.lastModified(); boolean hasNewer=false; for(String path:transaction.toArray()){ FilePath pathToCheck=null; switch(type){ case "js": pathToCheck = assetDirPath.resolve( assetResolver.getCleanJSPath(path) ); break; case "css": pathToCheck = assetDirPath.resolve( assetResolver.getCleanCSSPath(path) ); break; } if( pathToCheck != null && pathToCheck.toFile().lastModified() > lastModified ){ hasNewer=true; break; } } if(!hasNewer){ continue;//no elements of this transaction need to be processed. } } GroupedAssetTask<Object> transactionToProcess = new GroupedAssetTask<>( transaction, assetManager, fileUtils, proposedFilePath ); tasks.add(transactionToProcess); } return tasks; } public GroupedAssetTransaction startTransaction( String type, String compress ){ return startTransaction(type, compress, "false"); } public GroupedAssetTransaction startTransaction( String type, String compress, String shouldWrapJsInClosure ){ boolean useCompress="true".equals(compress) || "false".equals(compress); GroupedAssetTransaction transaction = new GroupedAssetTransaction( type, useCompress? "true".equals(compress): config.isEnableCompression(), "true".equals(shouldWrapJsInClosure) ); synchronized(transactions){ transactions.add(transaction); } return transaction; } }