Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
officejs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
officejs
Commits
5fccb361
Commit
5fccb361
authored
Aug 24, 2011
by
François Billioud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add comments and different example of storage nodes
parent
01620370
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
720 additions
and
242 deletions
+720
-242
UNGProject/unhosted/jio.js
UNGProject/unhosted/jio.js
+720
-242
No files found.
UNGProject/unhosted/jio.js
View file @
5fccb361
...
...
@@ -7,10 +7,17 @@
/**
* load dependencies
*/
includeJS
(
"
unhosted/sjcl.js
"
);
includeJS
(
"
unhosted/jquery.js
"
);
includeJS
(
"
unhosted/base64.js
"
);
var
ready
=
includeJS
([
//files to load
"
unhosted/sjcl.js
"
,
"
unhosted/jquery.js
"
,
"
unhosted/base64.js
"
],[
//element to check before being ready
$
]);
//wait until dependencies are ready
(
function
waitUntilLoaded
()
{
!
ready
()
?
setTimeout
(
waitUntilLoaded
,
50
)
:
script
();})()
function
script
()
{
/**
* JIO main object. Contains all IO methods
...
...
@@ -21,28 +28,33 @@
/**
* prepare and return the jio object
* @param jioData :
content of jio.json or method to get it
* @param applicant : (optional) information about the person/application needing this JIO object (allow limited
access)
* @param jioData : text or json
content of jio.json or method to get it
* @param applicant : (optional) information about the person/application needing this JIO object (used to limit
access)
* @return JIO object
*/
initialize
:
function
(
jioData
,
applicant
)
{
switch
(
typeof
jioData
)
{
case
"
string
"
:
this
.
jioFileContent
=
jioData
;
break
;
case
"
object
"
:
this
.
jioFileContent
=
JSON
.
stringify
(
jioData
);
break
;
case
"
function
"
:
this
.
jioFileContent
=
jioData
();
break
;
default
:
alert
(
"
Error while getting jio.json content
"
);
break
;
case
"
string
"
:
this
.
jioFileContent
=
jioData
;
break
;
case
"
object
"
:
this
.
jioFileContent
=
JSON
.
stringify
(
jioData
);
break
;
case
"
function
"
:
this
.
jioFileContent
=
jioData
();
break
;
default
:
alert
(
"
Error while getting jio.json content
"
);
break
;
}
this
.
storage
=
createStorage
(
JSON
.
parse
(
this
.
jioFileContent
),
applicant
)
//create the object allowing IO in storages
return
this
;
},
//IO
getLocation
:
function
()
{
return
this
.
location
},
userNameAvailable
:
function
()
{
return
this
.
storage
.
userNameAvailable
.
apply
(
this
.
storage
,
arguments
)},
loadDocument
:
function
()
{
return
this
.
storage
.
loadDocument
.
apply
(
this
.
storage
,
arguments
)},
saveDocument
:
function
()
{
return
this
.
storage
.
saveDocument
.
apply
(
this
.
storage
,
arguments
)},
deleteDocument
:
function
()
{
return
this
.
storage
.
deleteDocument
.
apply
(
this
.
storage
,
arguments
)},
getDocumentList
:
function
()
{
return
this
.
storage
.
getDocumentList
.
apply
(
this
.
storage
,
arguments
)}
/**
* return the state of JIO object
* @return true if ready, false otherwise
*/
isReady
:
function
()
{
return
this
.
jioFileContent
&&
this
.
storage
},
//IO functions
userNameAvailable
:
function
(
name
,
option
)
{
return
this
.
storage
.
userNameAvailable
.
apply
(
this
.
storage
,
arguments
)},
loadDocument
:
function
(
fileName
,
option
)
{
return
this
.
storage
.
loadDocument
.
apply
(
this
.
storage
,
arguments
)},
saveDocument
:
function
(
data
,
fileName
,
option
)
{
return
this
.
storage
.
saveDocument
.
apply
(
this
.
storage
,
arguments
)},
deleteDocument
:
function
(
file
,
option
)
{
return
this
.
storage
.
deleteDocument
.
apply
(
this
.
storage
,
arguments
)},
getDocumentList
:
function
(
option
)
{
return
this
.
storage
.
getDocumentList
.
apply
(
this
.
storage
,
arguments
)}
}
...
...
@@ -52,74 +64,126 @@
/*************************************************************************
************************* specific storages *****************************/
/************************************************************
*********************** DAVstorage *************************/
/**
* Class DAVStorage
* @class provides usual API to save/load/delete documents on a storage webDav
* @param data : object containing every element needed to build the storage :
* "userName" : the name of the user
* "location" : the complete url of the storage
* "provider" : the provider of the storage
* @param applicant : object containing inforamtion about the person/application needing this JIO object
*/
JIO
.
DAVStorage
=
function
(
data
,
applicant
)
{
this
.
userName
=
data
.
userName
;
this
.
applicationID
=
applicant
.
ID
;
this
.
applicationPassword
=
data
.
password
;
this
.
location
=
data
.
location
;
this
.
location
=
data
.
location
;
//complete url of the storage
this
.
provider
=
data
.
provider
;
//like "gmail.com", "yahoo.fr"...
}
JIO
.
DAVStorage
.
prototype
=
{
userNameAvailable
:
function
(
success
,
errorHandler
,
asyncronous
)
{
/**
* check if an user already exist
* @param name : the name you want to check
* @param option : optional object containing
* "success" : the function to execute when the check is done
* "errorHandler" : the function to execute if an error occures
* "asynchronous" : a boolean set to false if the request must be synchronous
* @return null if the request is asynchronous, true if the name is free, false otherwise
*/
userNameAvailable
:
function
(
name
,
option
)
{
var
isAvailable
=
null
;
$
.
ajax
({
url
:
this
.
location
+
"
/dav/
"
+
this
.
userN
ame
,
url
:
this
.
location
+
"
/dav/
"
+
n
ame
,
type
:
"
HEAD
"
,
async
:
asyncronous
||
true
,
success
:
function
()
{
isAvailable
=
true
;
instruction
();},
error
:
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to load
"
+
file
);
}
async
:
option
.
asyncronous
||
true
,
success
:
function
()
{
isAvailable
=
true
;
if
(
option
.
sucess
)
option
.
success
();},
error
:
option
.
errorHandler
||
function
(
type
)
{
if
(
type
.
status
==
404
)
{
isAvailable
=
false
;}
else
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to check
"
+
name
);}
}
});
return
isAvailable
;
//warning : always null if asyncronous
},
loadDocument
:
function
(
file
,
type
,
instruction
,
errorHandler
,
asyncronous
)
{
/**
* load a document in the storage
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* "type" : the type of data to store
* "success" : the function to execute when the load is done
* "errorHandler" : the function to execute if an error occures
* "asynchronous" : a boolean set to false if the request must be synchronous
* @return null if the request is asynchronous, the content of the document otherwise
*/
loadDocument
:
function
(
fileName
,
option
)
{
var
data
=
null
;
$
.
ajax
({
url
:
this
.
location
+
"
/dav/
"
+
this
.
userName
+
"
/
"
+
this
.
applicationID
+
"
/
"
+
fil
e
,
url
:
this
.
location
+
"
/dav/
"
+
this
.
userName
+
"
/
"
+
this
.
applicationID
+
"
/
"
+
fileNam
e
,
type
:
"
GET
"
,
async
:
asyncronous
||
true
,
dataType
:
type
,
async
:
option
.
asyncronous
||
true
,
dataType
:
option
.
type
||
"
text
"
,
headers
:
{
Authorization
:
"
Basic
"
+
Base64
.
encode
(
this
.
userName
+
"
:
"
+
this
.
applicationPassword
)},
fields
:
{
withCredentials
:
"
true
"
},
success
:
function
(
content
)
{
instruction
(
content
);
data
=
content
},
error
:
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to load
"
+
fil
e
);}
success
:
function
(
content
)
{
if
(
option
.
success
)
option
.
success
(
content
);
data
=
content
},
error
:
option
.
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to load
"
+
fileNam
e
);}
});
return
data
;
//warning : always null if asyncronous
},
saveDocument
:
function
(
newData
,
file
,
type
,
overwrite
,
instruction
,
oldData
,
errorHandler
)
{
var
storage
=
this
;
/**
* save a document in the storage
* @param data : the data to store
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* type : the type of data to store
* success : the function to execute when the save is done
* errorHandler : the function to execute if an error occures
* overwrite : a boolean set to true if the document has to be overwritten
* asynchronous : a boolean set to false if the request must be synchronous
* oldData : last data downloaded. Used to know if data has changed since last download and has to been merged
*/
saveDocument
:
function
(
data
,
fileName
,
option
)
{
var
storage
=
this
;
//save the context
//check if already exists and for diffs
this
.
loadDocument
(
file
,
type
,
function
(
serverData
)
{
merge
(
serverData
);
var
loadOption
=
{
type
:
option
.
type
,
asynchronous
:
false
,
//TODO : try to asynchronize
success
:
function
(
remoteData
)
{
merge
(
remoteData
);
},
function
(
type
)
{
errorHandler
:
function
(
type
)
{
if
(
type
.
status
==
404
)
{
save
();
}
else
{
errorHandler
||
save
();
option
.
errorHandler
||
save
();
}
},
false
);
}
}
this
.
loadDocument
(
fileName
,
loadOption
);
function
save
()
{
$
.
ajax
({
url
:
storage
.
location
+
"
/dav/
"
+
storage
.
userName
+
"
/
"
+
storage
.
applicationID
+
"
/
"
+
fil
e
,
url
:
storage
.
location
+
"
/dav/
"
+
storage
.
userName
+
"
/
"
+
storage
.
applicationID
+
"
/
"
+
fileNam
e
,
type
:
"
PUT
"
,
dataType
:
type
,
data
:
newData
,
async
:
option
.
asynchronous
||
true
,
dataType
:
option
.
type
||
"
text
"
,
data
:
data
,
headers
:
{
Authorization
:
"
Basic
"
+
Base64
.
encode
(
storage
.
userName
+
"
:
"
+
storage
.
applicationPassword
)},
fields
:
{
withCredentials
:
"
true
"
},
success
:
instruction
,
success
:
option
.
success
,
error
:
function
(
type
)
{
if
(
type
.
status
==
201
||
type
.
status
==
204
)
{
instruction
();}
//ajax thinks that 201 is an error...
else
{
error
:
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to save
"
+
file
);}
}
if
(
type
.
status
==
201
||
type
.
status
==
204
)
{
if
(
option
.
success
)
option
.
success
();}
//ajax thinks that 201 is an error...
else
{
option
.
errorHandler
?
option
.
errorHandler
.
call
(
this
,
type
)
:
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to save
"
+
fileName
);
}
}
});
}
function
merge
(
serverData
)
{
if
(
overwrit
e
)
{
if
(
option
.
overwrite
!==
fals
e
)
{
//if(diff(oldData,serverData)) {merge(newData, serverData);}
save
();
}
...
...
@@ -127,47 +191,68 @@
},
/**
* Delete a document or a list of documents
* @param file : fileName or array ogf fileNames
* @param instruction : instructions to execute when done
* @param errorHandler : what to do if the request fails
* Delete a document or a list of documents from the storage
* @param file : fileName or array of fileNames to delete
* @param option : optional object containing
* "success" : the function to execute when the delete is done. The function is executed only if every delete are successful
* "errorHandler" : the function to execute if an error occures
* "asynchronous" : a boolean set to false if the request must be synchronous
*/
deleteDocument
:
function
(
file
,
instruction
,
errorHandler
)
{
deleteDocument
:
function
(
file
,
option
)
{
var
storage
=
this
;
typeof
file
!=
Object
?
deleteFile
(
file
)
:
$
.
each
(
file
,
function
(
index
,
fileName
)
{
deleteFile
(
fileName
);});
function
deleteFile
(
fileName
)
{
var
fileName
=
typeof
file
==
"
string
"
?
file
:
file
.
pop
();
var
successFunction
=
generateSuccess
();
$
.
ajax
({
url
:
storage
.
location
+
"
/dav/
"
+
storage
.
userName
+
"
/
"
+
storage
.
applicationID
+
"
/
"
+
fileName
,
type
:
"
DELETE
"
,
async
:
option
.
asynchronous
||
true
,
headers
:
{
Authorization
:
"
Basic
"
+
Base64
.
encode
(
this
.
userName
+
"
:
"
+
this
.
applicationPassword
)},
fields
:
{
withCredentials
:
"
true
"
},
success
:
instru
ction
,
success
:
successFun
ction
,
error
:
function
(
type
)
{
if
(
type
.
status
==
201
||
type
.
status
==
204
)
{
instru
ction
();}
//ajax thinks that 201 is an error...
else
{
error
:
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to delete
"
+
file
);}
}
if
(
type
.
status
==
201
||
type
.
status
==
204
)
{
successFun
ction
();}
//ajax thinks that 201 is an error...
else
{
option
.
errorHandler
?
option
.
errorHandler
(
type
)
:
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to delete
"
+
fileName
);
}
}
});
function
generateSuccess
()
{
if
(
typeof
file
==
"
string
"
||
file
.
length
===
0
)
{
return
function
()
{
if
(
option
.
success
)
{
option
.
success
()}}
}
else
{
return
function
()
{
storage
.
deleteDocument
(
file
,
option
);}
}
}
},
getDocumentList
:
function
(
instruction
,
errorHandler
,
asyncronous
)
{
/**
* load the list of the documents in this storage
* @param option : optional object containing
* "success" : the function to execute when the load is done
* "errorHandler" : the function to execute if an error occures
* "asynchronous" : a boolean set to false if the request must be synchronous
* @return null if the request is asynchronous, the list of documents otherwise.
* @example {"file1":{fileName:"file1",creationDate:"Tue, 23 Aug 2011 15:18:32 GMT",lastModified:"Tue, 23 Aug 2011 15:18:32 GMT"},...}
*/
getDocumentList
:
function
(
option
)
{
var
storage
=
this
;
var
list
=
null
;
$
.
ajax
({
url
:
storage
.
location
+
"
/dav/
"
+
storage
.
userName
+
"
/
"
+
storage
.
applicationID
+
"
/
"
,
async
:
asyncronous
||
true
,
async
:
option
.
asyncronous
||
true
,
type
:
"
PROPFIND
"
,
dataType
:
"
xml
"
,
headers
:
{
Authorization
:
"
Basic
"
+
Base64
.
encode
(
this
.
userName
+
"
:
"
+
this
.
applicationPassword
),
Depth
:
"
1
"
},
fields
:
{
withCredentials
:
"
true
"
},
success
:
function
(
data
)
{
list
=
xml2jsonFileList
(
data
);
instruction
(
list
)},
error
:
function
(
type
)
{
error
:
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to load file list
"
);}
}
success
:
function
(
data
)
{
list
=
xml2jsonFileList
(
data
);
if
(
option
.
success
)
option
.
success
(
list
)},
error
:
option
.
errorHandler
||
function
(
type
)
{
alert
(
"
Error
"
+
type
.
status
+
"
: fail while trying to load file list
"
);
}
});
return
list
;
//warning : always null if asyncronous
function
xml2jsonFileList
(
xmlData
)
{
function
xml2jsonFileList
(
xmlData
)
{
//transform the xml into a list
var
fileList
=
{};
$
(
"
D
\\
:response
"
,
xmlData
)
.
each
(
function
(
i
,
data
){
...
...
@@ -183,13 +268,13 @@
delete
fileList
[
"
.htpasswd
"
];
return
fileList
;
}
function
xml2jsonFile
(
xmlData
)
{
function
xml2jsonFile
(
xmlData
)
{
//transform the xml about a file into json information
var
file
=
{};
file
.
lastModified
=
$
(
$
(
"
lp1
\\
:getlastmodified
"
,
xmlData
).
get
(
0
)).
text
();
file
.
creationDate
=
$
(
$
(
"
lp1
\\
:creationdate
"
,
xmlData
).
get
(
0
)).
text
();
return
file
;
}
function
fileName
(
xmlData
)
{
function
fileName
(
xmlData
)
{
//read the name of a file in the xml
var
string
=
$
(
$
(
"
D
\\
:href
"
,
xmlData
).
get
(
0
)).
text
()
var
T
=
string
.
split
(
"
/
"
);
return
T
[
T
.
length
-
1
]
?
T
[
T
.
length
-
1
]
:
T
[
T
.
length
-
2
]
+
"
/
"
;
...
...
@@ -197,48 +282,394 @@
}
}
/************************************************************
*********************** LocalStorage ************************/
/**
* Class LocalStorage
* this class provides usual API to save/load/delete documents on the localStorage
* @class provides usual API to save/load/delete documents on the localStorage
* @param data : object containing every element needed to build the storage :
* "userName" : the name of the user
* @param applicant : object containing inforamtion about the person/application needing this JIO object
*/
JIO
.
LocalStorage
=
function
(
userName
)
{
this
.
userName
=
userName
;
if
(
!
localStorage
.
getItem
(
this
.
userName
))
{
localStorage
[
this
.
userName
]
=
{}
}
//new user
JIO
.
LocalStorage
=
function
(
data
,
applicant
)
{
this
.
userName
=
data
.
userName
;
if
(
!
localStorage
.
getItem
(
this
.
userName
))
{
localStorage
[
this
.
userName
]
=
"
{}
"
}
//new user
this
.
documents
=
JSON
.
parse
(
localStorage
.
getItem
(
this
.
userName
));
//load documents
this
.
save
=
function
()
{
localStorage
[
this
.
userName
]
=
JSON
.
stringify
(
this
.
documents
);
}
}
JIO
.
LocalStorage
.
prototype
=
{
userNameAvailable
:
function
(
userName
)
{
return
localStorage
.
userName
;},
loadDocument
:
function
(
file
,
type
,
instruction
)
{
var
doc
=
this
.
userName
[
file
];
if
(
instruction
)
instruction
(
doc
);
return
doc
;
},
saveDocument
:
function
(
newData
,
file
,
type
,
overwrite
,
instruction
)
{
if
(
!
this
.
documents
[
file
]
||
overwrite
)
{
this
.
documents
[
file
]
=
newData
;
/**
* check if an user already exist
* @param name : the name you want to check
* @return true if the name is free, false otherwise
*/
userNameAvailable
:
function
(
name
)
{
return
localStorage
[
name
];},
/**
* load a document in the storage
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* "success" : the function to execute when the load is done
* "errorHandler" : the function to execute if an error occures
* @return the content of the document
*/
loadDocument
:
function
(
fileName
,
option
)
{
var
doc
=
this
.
documents
[
fileName
];
if
(
!
doc
)
{
if
(
option
.
errorHandler
)
{
var
error
=
{
status
:
404
,
message
:
"
document not found
"
};
return
option
.
errorHandler
(
error
);
}
else
{
return
false
;
}
}
else
{
if
(
option
.
success
)
{
return
option
.
success
(
doc
);
}
else
{
return
doc
}
}
},
/**
* save a document in the storage
* @param data : the data to store
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* success : the function to execute when the save is done
* errorHandler : the function to execute if an error occures
* overwrite : a boolean set to true if the document has to be overwritten
* oldData : last data downloaded. Used to know if data has changed since last download and has to been merged
*/
saveDocument
:
function
(
data
,
fileName
,
option
)
{
if
(
!
this
.
documents
[
fileName
]
||
option
.
overwrite
)
{
this
.
documents
[
fileName
]
=
data
;
this
.
save
();
if
(
instruction
)
instruction
();
if
(
option
.
success
)
option
.
success
();
}
else
{
var
error
=
{
status
:
403
,
message
:
"
document already exists
"
};
if
(
option
.
errorHandler
)
option
.
errorHandler
(
error
);
}
},
deleteDocument
:
function
(
file
,
instruction
)
{
typeof
file
!=
Object
?
deleteFile
(
file
)
:
$
.
each
(
file
,
function
(
index
,
fileName
)
{
deleteFile
(
fileName
);});
/**
* Delete a document or a list of documents from the storage
* @param file : fileName or array of fileNames to delete
* @param option : optional object containing
* "success" : the function to execute when the delete is done
* "errorHandler" : the function to execute if an error occures
*/
deleteDocument
:
function
(
file
,
option
)
{
oneOrEach
(
file
,
deleteFile
);
this
.
save
();
if
(
option
.
success
)
option
.
success
();
function
deleteFile
(
fileName
)
{
delete
this
.
documents
[
fileName
];
}
this
.
save
();
if
(
instruction
)
instruction
();
},
getDocumentList
:
function
(
instruction
)
{
/**
* load the list of the documents in this storage
* @param option : optional object containing
* "success" : the function to execute when the load is done
* "errorHandler" : the function to execute if an error occures
* @return null if the request is asynchronous, the list of documents otherwise.
* @example {"file1":{fileName:"file1",creationDate:"Tue, 23 Aug 2011 15:18:32 GMT",lastModified:"Tue, 23 Aug 2011 15:18:32 GMT"},...}
*/
getDocumentList
:
function
(
option
)
{
var
list
=
this
.
documents
;
if
(
instruction
)
instruction
(
list
);
if
(
option
.
success
)
option
.
success
(
list
);
return
list
;
},
save
:
function
()
{
localStorage
[
this
.
userName
]
=
JSON
.
stringify
(
this
.
documents
);
}
}
/***************************************************************
*********************** IndexedStorage *************************/
/**
* Class IndexedStorage
* @class provides usual API to create an index while storing documents
* @param data : object containing every element needed to build the storage
* "storage" : the storage to index
* @param applicant : object containing inforamtion about the person/application needing this JIO object
*/
JIO
.
IndexedStorage
=
function
(
data
,
applicant
)
{
this
.
storage
=
createStorage
(
data
.
storage
,
applicant
)
//create the object allowing IO in storages
this
.
index
=
null
;
//initialize the index
var
storage
=
this
;
(
function
initialize
()
{
//try to download jio.index
if
(
this
.
storage
)
{
this
.
storage
.
loadDocument
(
"
jio.index
"
,
"
text
"
,
function
(
data
)
{
storage
.
index
=
this
;},
function
(
error
)
{
if
(
error
.
status
==
404
)
{
createIndex
()}
else
{
alert
(
"
error
"
+
error
.
status
+
"
while trying to download jio.index
"
)}
});
}
else
{
//if the storage is not ready
setTimeout
(
initialize
,
50
);
}
})()
function
createIndex
()
{
//create a new index if doesn't exist
storage
.
index
=
{}
//for the moment, just consider that the folder is empty
}
}
JIO
.
IndexedStorage
.
prototype
=
{
/* delegate the call to the indexed storage */
userNameAvailable
:
function
()
{
return
this
.
storage
.
userNameAvailable
.
apply
(
this
.
storage
,
arguments
)},
/**
* load either a document or only its metaData
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* "metaDataOnly" : set to true if only metaData are wanted
* @return the content of metaData, or the content of the document
*/
loadDocument
:
function
(
fileName
,
option
)
{
return
option
.
metaDataOnly
?
this
.
getIndex
()[
fileName
]
:
this
.
storage
.
loadDocument
.
apply
(
this
.
storage
,
arguments
)
},
/**
* save a document in the storage and update its metaData
* @param data : the data to store
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* "success" : the function to execute when the save is done
* "metaData" : information to store about the document
*/
saveDocument
:
function
(
data
,
fileName
,
option
)
{
var
fileAlreadyExist
=
this
.
getIndex
()[
fileName
];
return
this
.
storage
.
saveDocument
(
data
,
fileName
,
generateSaveOption
(
fileAlreadyExist
));
function
generateSaveOption
(
fileAlreadyExist
)
{
var
indexedStorage
=
this
;
var
saveOption
=
copy
(
option
);
saveOption
.
success
=
function
(
data
)
{
var
time
=
Date
.
now
();
indexedStorage
.
getIndex
()[
fileName
]
=
option
.
metaData
;
indexedStorage
.
getIndex
()[
fileName
].
lastModified
=
time
;
indexedStorage
.
getIndex
()[
fileName
].
fileName
=
fileName
;
if
(
!
fileAlreadyExist
)
{
indexedStorage
.
getIndex
()[
fileName
].
creationDate
=
time
;}
indexedStorage
.
save
();
option
.
success
(
data
);
}
return
saveOption
}
},
/**
* Delete a document or a list of documents from the storage and remove its metaData from the index
* Data are deleted only if the delete is successful
* @param file : fileName or array of fileNames to delete
* @param option : optional object containing
* "success" : the function to execute when the delete is done
*/
deleteDocument
:
function
(
file
,
option
)
{
var
indexedStorage
=
this
;
var
newOption
=
copy
(
option
);
newOption
.
success
=
function
()
{
if
(
option
.
success
)
{
option
.
success
()}
oneOrEach
(
file
,
deleteFileData
);
indexedStorage
.
save
();
}
this
.
storage
.
deleteDocument
(
file
,
newOption
);
function
deleteFileData
(
fileName
)
{
delete
this
.
getIndex
()[
fileName
];
}
},
/**
* return the list of the documents in the index
* @param option : optional object containing
* "success" : the function to execute on the list
* @return the list of documents.
* @example {"file1":{fileName:"file1",creationDate:"Tue, 23 Aug 2011 15:18:32 GMT",lastModified:"Tue, 23 Aug 2011 15:18:32 GMT"},...}
*/
getDocumentList
:
function
(
option
)
{
var
list
=
this
.
getIndex
();
if
(
option
.
success
)
option
.
success
(
list
);
return
list
;
},
getIndex
:
function
()
{
return
this
.
index
},
save
:
function
()
{
this
.
storage
.
saveDocument
(
JSON
.
stringify
(
this
.
getIndex
()),
"
jio.index
"
,
"
text
"
,
true
);
}
}
/***************************************************************
*********************** ReplicateStorage *************************/
/**
* Class ReplicateStorage
* @class provides usual API to replicate save/load/delete in a list of storages
* @param data : object containing every element needed to build the storage :
* "storageList" : an array containing the different storages ([{"storage1":{...},...])
* @param applicant : object containing inforamtion about the person/application needing this JIO object
*/
JIO
.
ReplicateStorage
=
function
(
data
,
applicant
)
{
this
.
storageList
=
[];
for
(
var
i
=
0
;
i
<
data
.
storageList
.
length
;
i
++
)
{
//create each storage from the list
this
.
storageList
[
i
]
=
createStorage
(
data
.
storageList
[
i
],
applicant
);
}
}
JIO
.
ReplicateStorage
.
prototype
=
{
/**
* check if an user already exists
* @param name : the name you want to check
* @param option : optional object containing
* "errorHandler" : the function to execute if an error occures
* @return the answer of the first storage able to answer
*/
userNameAvailable
:
function
(
name
,
option
)
{
return
tryCheckUser
(
this
.
storageList
.
slice
());
function
tryCheckUser
(
storageList
)
{
var
storage
=
storageList
.
pop
();
var
newOption
=
copy
(
option
);
newOption
.
errorHandler
=
generateErrorHandler
(
storageList
);
return
storage
.
userNameAvailable
(
name
,
newOption
);
}
function
generateErrorHandler
(
storageList
)
{
return
storageList
.
length
>
0
?
function
()
{
tryCheckUser
(
storageList
);}
:
option
.
errorHandler
;
}
},
/**
* load a document in the storage
* @param fileName : the name of the file where the data will be stored
* @param option : optional object containing
* "errorHandler" : the function to execute if an error occures
* @return the content of the document sent by the first storage able to
*/
loadDocument
:
function
(
fileName
,
option
)
{
return
tryLoadDocument
(
this
.
storageList
.
slice
());
function
tryLoadDocument
(
storageList
)
{
var
storage
=
storageList
.
pop
();
var
newOption
=
copy
(
option
);
newOption
.
errorHandler
=
generateErrorHandler
(
storageList
);
return
storage
.
loadDocument
(
fileName
,
newOption
);
}
function
generateErrorHandler
(
storageList
)
{
return
storageList
.
length
>
0
?
function
()
{
tryLoadDocument
(
storageList
);}
:
option
.
errorHandler
;
}
},
/**
* save the document in each storage (simply delegate the call to each storage. Perhaps the success function sould be executed only once?)
* @param data : the data to store
* @param fileName : the name of the file where the data will be stored
* @param option : optional object
*/
saveDocument
:
function
(
data
,
fileName
,
option
)
{
for
(
var
element
in
this
.
storageList
)
{
this
.
storageList
[
element
].
saveDocument
(
data
,
fileName
,
option
);
}
},
/**
* delete the document in each storage (simply delegate the call to each storage. Perhaps the success function sould be executed only once?)
* @param file : fileName or array of fileNames to delete
* @param option : optional object
*/
deleteDocument
:
function
(
file
,
option
)
{
for
(
var
element
in
this
.
storageList
)
{
this
.
storageList
[
element
].
deleteDocument
(
file
,
option
);
}
},
/**
* load the list of the documents in this storage
* @param option : optional object containing
* "errorHandler" : the function to execute if an error occures
* @return the answer of the first storage able to answer
* @example {"file1":{fileName:"file1",creationDate:"Tue, 23 Aug 2011 15:18:32 GMT",lastModified:"Tue, 23 Aug 2011 15:18:32 GMT"},...}
*/
getDocumentList
:
function
(
option
)
{
return
tryGetDocumentList
(
this
.
storageList
.
slice
());
function
tryGetDocumentList
(
storageList
)
{
var
storage
=
storageList
.
pop
();
var
newOption
=
copy
(
option
);
newOption
.
errorHandler
=
generateErrorHandler
(
storageList
);
return
storage
.
getDocumentList
(
newOption
);
}
function
generateErrorHandler
(
storageList
)
{
return
storageList
.
length
>
0
?
function
()
{
tryGetDocumentList
(
storageList
);}
:
option
.
errorHandler
;
}
}
}
/***************************************************************
*********************** MultipleStorage *************************/
/**
* Class MultipleStorage
* @class provides usual API to save/load/delete documents in a list of storages
* @param data : object containing every element needed to build the storage :
* "storageList" : an object containing the different storages ({"storage1":{...},...})
* @param applicant : object containing inforamtion about the person/application needing this JIO object
*/
JIO
.
MultipleStorage
=
function
(
data
,
applicant
)
{
this
.
storageList
=
{};
for
(
var
storage
in
data
.
storageList
)
{
//create each storage from the list
this
.
storageList
[
storage
]
=
createStorage
(
data
.
storageList
[
storage
],
applicant
);
}
}
JIO
.
MultipleStorage
.
prototype
=
{
userNameAvailable
:
function
(
userName
,
option
)
{
if
(
option
.
location
)
{
//TODO : think about writing location as a string "a/b/c" in case of spate of multipleStorages
this
.
storageList
[
option
.
location
].
userNameAvailable
(
userName
,
option
)
}
else
{
//TODO
}
},
//TODO /return this.storage.userNameAvailable.apply(this.storage,arguments)},
loadDocument
:
function
(
fileName
,
option
)
{
if
(
option
.
location
)
{
this
.
storageList
[
option
.
location
].
loadDocument
(
fileName
,
option
)
}
else
{
//TODO
}
},
saveDocument
:
function
(
data
,
fileName
,
option
)
{
if
(
option
.
location
)
{
this
.
storageList
[
option
.
location
].
saveDocument
(
data
,
fileName
,
option
)
}
else
{
//TODO
}
},
deleteDocument
:
function
(
fileName
,
option
)
{
if
(
option
.
location
)
{
this
.
storageList
[
option
.
location
].
deleteDocument
(
fileName
,
option
)
}
else
{
//TODO
}
},
getDocumentList
:
function
(
option
)
{
if
(
option
.
location
)
{
this
.
storageList
[
option
.
location
].
getDocumentList
(
option
)
}
else
{
//TODO
}
}
}
/*************************************************************************
*************************** other functions *****************************/
...
...
@@ -269,9 +700,10 @@
*/
function
createStorage
(
data
,
applicant
)
{
switch
(
data
.
type
)
{
case
"
dav
"
:
return
new
JIO
.
DAVStorage
(
data
,
applicant
);
break
;
//case "multipleStorage": return new JIO.MultipleStorage(data, applicantID, applicantPassword);break;
//case "replicateStorage": return new JIO.ReplicateStorage(data, applicantID, applicantPassword);break;
case
"
dav
"
:
return
new
JIO
.
DAVStorage
(
data
,
applicant
);
break
;
case
"
index
"
:
return
new
JIO
.
IndexedStorage
(
data
,
applicant
);
break
;
case
"
multiple
"
:
return
new
JIO
.
MultipleStorage
(
data
,
applicant
);
break
;
case
"
replicate
"
:
return
new
JIO
.
ReplicateStorage
(
data
,
applicant
);
break
;
//etc
default
:
var
waitedNode
=
null
;
//create a custom storage from a js file
$
.
ajax
({
...
...
@@ -287,13 +719,59 @@
}
}
function
includeJS
(
file
)
{
var
object
=
document
.
createElement
(
"
script
"
);
object
.
type
=
"
text/javascript
"
;
object
.
src
=
file
;
$
(
"
head
"
).
append
(
object
);
/**
* return a shallow copy of the object parameter
* @param object : the object to copy
* @return a shallow copy of the object
*/
function
copy
(
object
)
{
$
.
extend
({},
object
);
}
/**
* delegate a function to a non-object element, or to each element of an array of non-object elements
* @param element : a non-object element, or an array of non-object elements
* @param f : function to apply
*/
function
oneOrEach
(
element
,
f
)
{
typeof
element
!=
"
object
"
?
f
(
element
)
:
$
.
each
(
element
,
function
(
index
,
fileName
)
{
f
(
fileName
);})
}
/**
* include js files
* @param url : path or array of paths of the js file(s)
* @param flag : (optional) array of elements allowing to know if dependencies are ready
* @return a ready function which returns true only if the dependencies are ready
* @example : includeJS("jquery.js",[$]);
*/
function
includeJS
(
url
,
flag
)
{
oneOrEach
(
url
,
includeElement
);
return
function
()
{
return
checkArray
(
flag
.
slice
());
}
function
includeElement
(
element
)
{
//include a js file
var
head
=
window
.
document
.
getElementsByTagName
(
'
head
'
)[
0
];
var
script
=
window
.
document
.
createElement
(
'
script
'
);
script
.
setAttribute
(
'
src
'
,
url
);
script
.
setAttribute
(
'
type
'
,
'
text/javascript
'
);
head
.
appendChild
(
script
);
}
function
checkElement
(
element
)
{
//check if a script is ready
switch
(
typeof
element
)
{
case
"
function
"
:
return
element
.
call
(
this
);
break
;
case
"
undefined
"
:
return
false
;
break
;
case
"
object
"
:
return
true
;
}
}
function
checkArray
(
array
)
{
//recursive function to check if elements are ready
if
(
!
array
)
return
true
;
var
head
=
array
.
pop
();
return
checkElement
(
head
)
&&
checkArray
(
array
);
}
}
window
.
JIO
=
JIO
;
//the name to use for the framework. Ex : JIO.initialize(...)
}
})();
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment