module Text.XML.HXT.Arrow.XmlState.URIHandling
where
import Control.Arrow
import Control.Arrow.ArrowList
import Control.Arrow.ArrowIf
import Control.Arrow.ArrowIO
import Control.Monad ( mzero
, mplus )
import Text.XML.HXT.Arrow.XmlArrow
import Text.XML.HXT.Arrow.XmlState.TypeDefs
import Text.XML.HXT.Arrow.XmlState.TraceHandling
import Data.Maybe
import Network.URI ( URI
, escapeURIChar
, isUnescapedInURI
, nonStrictRelativeTo
, parseURIReference
, uriAuthority
, uriFragment
, uriPath
, uriPort
, uriQuery
, uriRegName
, uriScheme
, uriUserInfo
)
import System.Directory ( getCurrentDirectory )
setBaseURI :: IOStateArrow s String String
setBaseURI :: forall s. IOStateArrow s String String
setBaseURI = Selector XIOSysState String -> IOStateArrow s String String
forall c s. Selector XIOSysState c -> IOStateArrow s c c
setSysVar Selector XIOSysState String
theBaseURI
IOStateArrow s String String
-> IOStateArrow s String String -> IOStateArrow s String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
Int -> (String -> String) -> IOStateArrow s String String
forall b s. Int -> (b -> String) -> IOStateArrow s b b
traceValue Int
2 ((String
"setBaseURI: new base URI is " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show)
getBaseURI :: IOStateArrow s b String
getBaseURI :: forall s b. IOStateArrow s b String
getBaseURI = Selector XIOSysState String -> IOStateArrow s b String
forall c s b. Selector XIOSysState c -> IOStateArrow s b c
getSysVar Selector XIOSysState String
theBaseURI
IOStateArrow s b String
-> IOSLA (XIOState s) String String -> IOStateArrow s b String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
( ( IOSLA (XIOState s) String String
forall s b. IOStateArrow s b String
getDefaultBaseURI
IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
IOSLA (XIOState s) String String
forall s. IOStateArrow s String String
setBaseURI
IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
IOSLA (XIOState s) String String
forall s b. IOStateArrow s b String
getBaseURI
)
IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
forall b c.
IOSLA (XIOState s) b b
-> IOSLA (XIOState s) b c -> IOSLA (XIOState s) b b
forall (a :: * -> * -> *) b c. ArrowIf a => a b b -> a b c -> a b b
`when`
(String -> Bool) -> IOSLA (XIOState s) String String
forall b. (b -> Bool) -> IOSLA (XIOState s) b b
forall (a :: * -> * -> *) b. ArrowList a => (b -> Bool) -> a b b
isA String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
)
changeBaseURI :: IOStateArrow s String String
changeBaseURI :: forall s. IOStateArrow s String String
changeBaseURI = IOStateArrow s String String
forall s. IOStateArrow s String String
mkAbsURI IOStateArrow s String String
-> IOStateArrow s String String -> IOStateArrow s String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> IOStateArrow s String String
forall s. IOStateArrow s String String
setBaseURI
setDefaultBaseURI :: String -> IOStateArrow s b String
setDefaultBaseURI :: forall s b. String -> IOStateArrow s b String
setDefaultBaseURI String
base = ( if String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
base
then (b -> IO String) -> IOSLA (XIOState s) b String
forall b c. (b -> IO c) -> IOSLA (XIOState s) b c
forall (a :: * -> * -> *) b c. ArrowIO a => (b -> IO c) -> a b c
arrIO b -> IO String
forall {p}. p -> IO String
getDir
else String -> IOSLA (XIOState s) b String
forall c b. c -> IOSLA (XIOState s) b c
forall (a :: * -> * -> *) c b. ArrowList a => c -> a b c
constA String
base
)
IOSLA (XIOState s) b String
-> IOSLA (XIOState s) String String -> IOSLA (XIOState s) b String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
Selector XIOSysState String -> IOSLA (XIOState s) String String
forall c s. Selector XIOSysState c -> IOStateArrow s c c
setSysVar Selector XIOSysState String
theDefaultBaseURI
IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
Int -> (String -> String) -> IOSLA (XIOState s) String String
forall b s. Int -> (b -> String) -> IOStateArrow s b b
traceValue Int
2 ((String
"setDefaultBaseURI: new default base URI is " String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. Show a => a -> String
show)
where
getDir :: p -> IO String
getDir p
_ = do
String
cwd <- IO String
getCurrentDirectory
String -> IO String
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String
"/file/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
normalize String
cwd String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"/")
normalize :: String -> String
normalize wd' :: String
wd'@(Char
d : Char
':' : String
_)
| Char
d Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'A'..Char
'Z']
Bool -> Bool -> Bool
||
Char
d Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Char
'a'..Char
'z']
= Char
'/' Char -> String -> String
forall a. a -> [a] -> [a]
: (Char -> String) -> String -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> String
win32ToUriChar String
wd'
normalize String
wd' = (Char -> String) -> String -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> String
escapeNonUriChar String
wd'
win32ToUriChar :: Char -> String
win32ToUriChar Char
'\\' = String
"/"
win32ToUriChar Char
c = Char -> String
escapeNonUriChar Char
c
escapeNonUriChar :: Char -> String
escapeNonUriChar Char
c = (Char -> Bool) -> Char -> String
escapeURIChar Char -> Bool
isUnescapedInURI Char
c
getDefaultBaseURI :: IOStateArrow s b String
getDefaultBaseURI :: forall s b. IOStateArrow s b String
getDefaultBaseURI = Selector XIOSysState String -> IOStateArrow s b String
forall c s b. Selector XIOSysState c -> IOStateArrow s b c
getSysVar Selector XIOSysState String
theDefaultBaseURI
IOStateArrow s b String
-> IOSLA (XIOState s) String String -> IOStateArrow s b String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
( ( String -> IOSLA (XIOState s) String String
forall s b. String -> IOStateArrow s b String
setDefaultBaseURI String
""
IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>>
IOSLA (XIOState s) String String
forall s b. IOStateArrow s b String
getDefaultBaseURI
)
IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
forall b c.
IOSLA (XIOState s) b b
-> IOSLA (XIOState s) b c -> IOSLA (XIOState s) b b
forall (a :: * -> * -> *) b c. ArrowIf a => a b b -> a b c -> a b b
`when` (String -> Bool) -> IOSLA (XIOState s) String String
forall b. (b -> Bool) -> IOSLA (XIOState s) b b
forall (a :: * -> * -> *) b. ArrowList a => (b -> Bool) -> a b b
isA String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
)
runInLocalURIContext :: IOStateArrow s b c -> IOStateArrow s b c
runInLocalURIContext :: forall s b c. IOStateArrow s b c -> IOStateArrow s b c
runInLocalURIContext IOStateArrow s b c
f = Selector XIOSysState String
-> IOStateArrow s b c -> IOStateArrow s b c
forall c s a b.
Selector XIOSysState c -> IOStateArrow s a b -> IOStateArrow s a b
localSysVar Selector XIOSysState String
theBaseURI IOStateArrow s b c
f
parseURIReference' :: String -> Maybe URI
parseURIReference' :: String -> Maybe URI
parseURIReference' String
uri
= String -> Maybe URI
parseURIReference String
uri
Maybe URI -> Maybe URI -> Maybe URI
forall a. Maybe a -> Maybe a -> Maybe a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus`
( if Bool
unesc
then String -> Maybe URI
parseURIReference String
uri'
else Maybe URI
forall a. Maybe a
forall (m :: * -> *) a. MonadPlus m => m a
mzero
)
where
unesc :: Bool
unesc = Bool -> Bool
not (Bool -> Bool) -> (String -> Bool) -> String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isUnescapedInURI (String -> Bool) -> String -> Bool
forall a b. (a -> b) -> a -> b
$ String
uri
escape :: Char -> String
escape Char
'\\' = String
"/"
escape Char
c = (Char -> Bool) -> Char -> String
escapeURIChar Char -> Bool
isUnescapedInURI Char
c
uri' :: String
uri' = (Char -> String) -> String -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Char -> String
escape String
uri
expandURIString :: String -> String -> Maybe String
expandURIString :: String -> String -> Maybe String
expandURIString String
uri String
base
= do
URI
base' <- String -> Maybe URI
parseURIReference' String
base
URI
uri' <- String -> Maybe URI
parseURIReference' String
uri
let abs' :: URI
abs' = URI -> URI -> URI
nonStrictRelativeTo URI
uri' URI
base'
String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ URI -> String
forall a. Show a => a -> String
show URI
abs'
expandURI :: ArrowXml a => a (String, String) String
expandURI :: forall (a :: * -> * -> *). ArrowXml a => a (String, String) String
expandURI
= ((String, String) -> [String]) -> a (String, String) String
forall b c. (b -> [c]) -> a b c
forall (a :: * -> * -> *) b c. ArrowList a => (b -> [c]) -> a b c
arrL (Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList (Maybe String -> [String])
-> ((String, String) -> Maybe String)
-> (String, String)
-> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String -> Maybe String)
-> (String, String) -> Maybe String
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry String -> String -> Maybe String
expandURIString)
mkAbsURI :: IOStateArrow s String String
mkAbsURI :: forall s. IOStateArrow s String String
mkAbsURI
= ( IOSLA (XIOState s) String String
forall b. IOSLA (XIOState s) b b
forall (a :: * -> * -> *) b. ArrowList a => a b b
this IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String String
-> IOSLA (XIOState s) String (String, String)
forall b c c'.
IOSLA (XIOState s) b c
-> IOSLA (XIOState s) b c' -> IOSLA (XIOState s) b (c, c')
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& IOSLA (XIOState s) String String
forall s b. IOStateArrow s b String
getBaseURI ) IOSLA (XIOState s) String (String, String)
-> IOSLA (XIOState s) (String, String) String
-> IOSLA (XIOState s) String String
forall {k} (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> IOSLA (XIOState s) (String, String) String
forall (a :: * -> * -> *). ArrowXml a => a (String, String) String
expandURI
getSchemeFromURI :: ArrowList a => a String String
getSchemeFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getSchemeFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
scheme
where
scheme :: URI -> String
scheme = String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String) -> (URI -> String) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. URI -> String
uriScheme
getRegNameFromURI :: ArrowList a => a String String
getRegNameFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getRegNameFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
host
where
host :: URI -> String
host = String -> (URIAuth -> String) -> Maybe URIAuth -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" URIAuth -> String
uriRegName (Maybe URIAuth -> String)
-> (URI -> Maybe URIAuth) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. URI -> Maybe URIAuth
uriAuthority
getPortFromURI :: ArrowList a => a String String
getPortFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getPortFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
port
where
port :: URI -> String
port = (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
':') (String -> String) -> (URI -> String) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (URIAuth -> String) -> Maybe URIAuth -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" URIAuth -> String
uriPort (Maybe URIAuth -> String)
-> (URI -> Maybe URIAuth) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. URI -> Maybe URIAuth
uriAuthority
getUserInfoFromURI :: ArrowList a => a String String
getUserInfoFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getUserInfoFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
ui
where
ui :: URI -> String
ui = String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (URI -> String) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'@') (String -> String) -> (URI -> String) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (URI -> String) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> (URIAuth -> String) -> Maybe URIAuth -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" URIAuth -> String
uriUserInfo (Maybe URIAuth -> String)
-> (URI -> Maybe URIAuth) -> URI -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. URI -> Maybe URIAuth
uriAuthority
getPathFromURI :: ArrowList a => a String String
getPathFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getPathFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
uriPath
getQueryFromURI :: ArrowList a => a String String
getQueryFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getQueryFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
uriQuery
getFragmentFromURI :: ArrowList a => a String String
getFragmentFromURI :: forall (a :: * -> * -> *). ArrowList a => a String String
getFragmentFromURI = (URI -> String) -> a String String
forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
uriFragment
getPartFromURI :: ArrowList a => (URI -> String) -> a String String
getPartFromURI :: forall (a :: * -> * -> *).
ArrowList a =>
(URI -> String) -> a String String
getPartFromURI URI -> String
sel
= (String -> [String]) -> a String String
forall b c. (b -> [c]) -> a b c
forall (a :: * -> * -> *) b c. ArrowList a => (b -> [c]) -> a b c
arrL (Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList (Maybe String -> [String])
-> (String -> Maybe String) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe String
getPart)
where
getPart :: String -> Maybe String
getPart String
s = do
URI
uri <- String -> Maybe URI
parseURIReference' String
s
String -> Maybe String
forall a. a -> Maybe a
forall (m :: * -> *) a. Monad m => a -> m a
return (URI -> String
sel URI
uri)