module Java.JAR
(readManifest,
readJAR,
addJAR
) where
import Control.Monad.Trans (liftIO)
import qualified Control.Monad.State as St
import Data.List
import qualified Codec.Archive.LibZip as Zip
import Java.ClassPath
import Java.JAR.Archive
import Java.META
readManifest :: Zip.Archive (Maybe Manifest)
readManifest = do
let manifestPath = "META-INF/MANIFEST.MF"
files <- Zip.fileNames []
if manifestPath `elem` files
then do
content <- Zip.fileContents [] manifestPath
case parseMeta content of
Left e -> fail $ show e
Right meta -> return $ Just (loadSpec meta)
else return Nothing
readOne :: FilePath -> String -> Zip.Archive [Tree CPEntry]
readOne jarfile str = do
files <- Zip.fileNames []
return $ mapF (NotLoadedJAR jarfile) (buildTree $ filter good files)
where
good name = (str `isPrefixOf` name) && (".class" `isSuffixOf` name)
readJAR :: FilePath -> IO [Tree CPEntry]
readJAR jarfile = do
r <- Zip.withArchive [] jarfile $ do
m <- readManifest
case m of
Nothing -> return Nothing
Just mf -> do
trees <- mapM (readOne jarfile) (map meName $ manifestEntries mf)
let forest = merge (concat trees)
return (Just forest)
case r of
Nothing -> readAllJAR jarfile
Just f -> return f
addJAR :: FilePath -> ClassPath ()
addJAR jarfile = do
classes <- liftIO $ readJAR jarfile
cp <- St.get
let cp' = merge $ cp ++ classes
St.put cp'