Back to index

lightning-sunbird  0.9+nobinonly
regchrome.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Christopher Blizzard. Portions created by Christopher Blizzard are Copyright (C) Christopher Blizzard.  All Rights Reserved.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsIServiceManager.h"
00039 #include "nsCOMPtr.h"
00040 #include "nsIChromeRegistry.h"
00041 
00042 #include "rdf.h"
00043 #include "nsIRDFResource.h"
00044 #include "nsIRDFService.h"
00045 #include "nsIRDFContainer.h"
00046 
00047 #include "nsIFile.h"
00048 #include "nsAppDirectoryServiceDefs.h"
00049 
00050 #include "nsNetUtil.h"
00051 
00052 #include "nsString.h"
00053 
00054 #include "plgetopt.h"
00055 
00056 #include <stdlib.h>             // for exit()
00057 
00058 static const char uri_prefix[] = "http://www.mozilla.org/rdf/chrome#";
00059 static const char urn_prefix[] = "urn:mozilla:";
00060 
00061 // this is nasty - this is in nsChromeRegistry.h, but to include that,
00062 // we double our REQUIRES dependencies. We need the CID rather than
00063 // the ContractID because we need to guarantee that we're getting the
00064 // RDF-based chrome registry in order to build up chrome.rdf
00065 
00066 // {D8C7D8A2-E84C-11d2-BF87-00105A1B0627}
00067 #define NS_CHROMEREGISTRY_CID \
00068 { 0xd8c7d8a2, 0xe84c, 0x11d2, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
00069 
00070 static NS_DEFINE_CID(kChromeRegistryCID, NS_CHROMEREGISTRY_CID);
00071 
00072 nsresult
00073 WritePropertiesTo(nsIRDFDataSource*, const char* aProviderType, FILE* out);
00074 
00075 nsresult
00076 WriteAttributes(nsIRDFDataSource*, const char* aProviderType, const char* aProvider,
00077                 nsIRDFResource* aResource,
00078                 FILE* out);
00079 
00080 void
00081 TranslateResourceValue(const char* aProviderType,
00082                        const char* aProvider,
00083                        const char* aArc,
00084                        const char* aResourceValue,
00085                        nsACString& aResult);
00086 
00087 nsresult WriteProperties(const char* properties_file);
00088 
00089 void print_help();
00090 
00091 int main(int argc, char **argv)
00092 {
00093     const char* properties_filename = nsnull;
00094 
00095     PLOptState* optstate = PL_CreateOptState(argc, argv, "p:");
00096     
00097     while (PL_GetNextOpt(optstate) == PL_OPT_OK) {
00098         switch (optstate->option) {
00099         case 'p':               // output properties file
00100             properties_filename = optstate->value;
00101             break;
00102         case '?':
00103             print_help();
00104             exit(1);
00105             break;
00106         }
00107     }
00108     PL_DestroyOptState(optstate);
00109 
00110     NS_InitXPCOM2(nsnull, nsnull, nsnull);
00111 
00112     nsCOMPtr <nsIChromeRegistry> chromeReg = 
00113         do_GetService(kChromeRegistryCID);
00114     if (!chromeReg) {
00115         NS_WARNING("chrome check couldn't get the chrome registry");
00116         return NS_ERROR_FAILURE;
00117     }
00118     chromeReg->CheckForNewChrome();
00119 
00120     // ok, now load the rdf that just got written
00121     if (properties_filename)
00122         WriteProperties(properties_filename);
00123 
00124     // release the chrome registry before we shutdown XPCOM
00125     chromeReg = 0;
00126     NS_ShutdownXPCOM(nsnull);
00127     return 0;
00128 }
00129 
00130 
00131 nsresult
00132 WritePropertiesTo(nsIRDFDataSource* aDataSource,
00133                   const char* aProviderType, FILE* out)
00134 {
00135 
00136     // attempt to mimic nsXMLRDFDataSource::Flush?
00137     nsCOMPtr<nsIRDFService> rdfService =
00138         do_GetService("@mozilla.org/rdf/rdf-service;1");
00139     
00140     nsCOMPtr<nsIRDFResource> providerRoot;
00141     nsCAutoString urn(NS_LITERAL_CSTRING(urn_prefix) +
00142                       nsDependentCString(aProviderType) + NS_LITERAL_CSTRING(":root"));
00143 
00144     rdfService->GetResource(urn,
00145                             getter_AddRefs(providerRoot));
00146 
00147     nsCOMPtr<nsIRDFContainer> providerContainer =
00148         do_CreateInstance("@mozilla.org/rdf/container;1");
00149 
00150     providerContainer->Init(aDataSource, providerRoot);
00151 
00152     nsCOMPtr<nsISimpleEnumerator> providers;
00153     providerContainer->GetElements(getter_AddRefs(providers));
00154 
00155     PRBool hasMore;
00156     providers->HasMoreElements(&hasMore);
00157     for (; hasMore; providers->HasMoreElements(&hasMore)) {
00158         nsCOMPtr<nsISupports> supports;
00159         providers->GetNext(getter_AddRefs(supports));
00160 
00161         nsCOMPtr<nsIRDFResource> kid = do_QueryInterface(supports);
00162 
00163         const char* providerUrn;
00164         kid->GetValueConst(&providerUrn);
00165         
00166         // remove the prefix, the provider type, and the trailing ':'
00167         // (the compiler will optimize out the -1 + 1
00168         providerUrn += (sizeof(urn_prefix)-1) + strlen(aProviderType) + 1;
00169 
00170         WriteAttributes(aDataSource, aProviderType, providerUrn, kid, out);
00171     }
00172 
00173     return NS_OK;
00174 }
00175 
00176 
00177 nsresult
00178 WriteAttributes(nsIRDFDataSource* aDataSource,
00179                 const char* aProviderType,
00180                 const char* aProvider,
00181                 nsIRDFResource* aResource, FILE* out)
00182 {
00183     nsresult rv;
00184     
00185     nsCOMPtr<nsISimpleEnumerator> arcs;
00186     rv = aDataSource->ArcLabelsOut(aResource, getter_AddRefs(arcs));
00187     if (NS_FAILED(rv))
00188         return rv;
00189 
00190     PRBool hasMore;
00191     rv = arcs->HasMoreElements(&hasMore);
00192     if (NS_FAILED(rv))
00193         return rv;
00194 
00195 
00196     for (; hasMore; arcs->HasMoreElements(&hasMore)) {
00197         nsCOMPtr<nsISupports> supports;
00198         arcs->GetNext(getter_AddRefs(supports));
00199 
00200         nsCOMPtr<nsIRDFResource> arc = do_QueryInterface(supports);
00201 
00202         const char* arcValue;
00203         arc->GetValueConst(&arcValue);
00204         arcValue += (sizeof(uri_prefix)-1); // skip past prefix
00205          
00206         // get the literal value on the other end
00207         nsCOMPtr<nsIRDFNode> valueNode;
00208         aDataSource->GetTarget(aResource, arc, PR_TRUE, 
00209                                getter_AddRefs(valueNode));
00210          
00211         nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(valueNode);
00212         if (literal) {
00213             const PRUnichar* literalValue;
00214             literal->GetValueConst(&literalValue);
00215             fprintf(out, "%s.%s.%s=%s\n", aProviderType, aProvider, arcValue, NS_ConvertUCS2toUTF8(literalValue).get());
00216         }
00217 
00218         nsCOMPtr<nsIRDFResource> resource = do_QueryInterface(valueNode);
00219         if (resource) {
00220             const char* resourceValue;
00221             resource->GetValueConst(&resourceValue);
00222             
00223             nsCAutoString translatedValue;
00224             TranslateResourceValue(aProviderType, aProvider,
00225                                    arcValue, resourceValue, translatedValue);
00226             fprintf(out, "%s.%s.%s=%s\n", aProviderType, aProvider, arcValue, translatedValue.get());
00227         }
00228     }
00229 
00230     return NS_OK;
00231 }
00232     
00233 nsresult WriteProperties(const char* properties_file)
00234 {
00235     FILE* props;
00236     printf("writing to %s\n", properties_file);
00237     if (!(props = fopen(properties_file, "w"))) {
00238         printf("Could not write to %s\n", properties_file);
00239         return NS_ERROR_FAILURE;
00240     }
00241 
00242     nsCOMPtr<nsIFile> chromeFile;
00243     nsresult rv = NS_GetSpecialDirectory(NS_APP_CHROME_DIR, getter_AddRefs(chromeFile));
00244     if(NS_FAILED(rv)) {
00245         fclose(props);
00246         return rv;
00247     }
00248 
00249     chromeFile->AppendNative(NS_LITERAL_CSTRING("chrome.rdf"));
00250     
00251     nsCAutoString pathURL;
00252     NS_GetURLSpecFromFile(chromeFile, pathURL);
00253 
00254     nsCOMPtr<nsIRDFService> rdf = 
00255         do_GetService("@mozilla.org/rdf/rdf-service;1");
00256 
00257     nsCOMPtr<nsIRDFDataSource> chromeDS;
00258     rdf->GetDataSource(pathURL.get(), getter_AddRefs(chromeDS));
00259 
00260     WritePropertiesTo(chromeDS, "package", props);
00261     WritePropertiesTo(chromeDS, "skin", props);
00262     WritePropertiesTo(chromeDS, "locale", props);
00263 
00264     fclose(props);
00265     return NS_OK;
00266 }
00267 
00268 void print_help() {
00269 
00270     printf("Usage: regchrome [-p file.properties]\n"
00271            "Registers chrome by scanning installed-chrome.txt\n"
00272            "\n"
00273            "Options: \n"
00274            "  -p file.properties    Output a flat-file version of the registry to\n"
00275            "                        the specified file\n");
00276 
00277 }
00278 
00279 void
00280 TranslateResourceValue(const char* aProviderType,
00281                        const char* aProvider,
00282                        const char* aArc,
00283                        const char* aResourceValue,
00284                        nsACString& aResult)
00285 {
00286     PRUint32 chopStart=0, chopEnd=0; // bytes to chop off the front/back of aResourceValue
00287 
00288     static const char localeUrn[] = "urn:mozilla:locale:";
00289     if ((strcmp(aArc, "selectedLocale") == 0) &&
00290         (strncmp(aResourceValue, localeUrn, sizeof(localeUrn)-1) == 0)) {
00291         
00292         chopStart = sizeof(localeUrn) - 1;
00293         chopEnd = strlen(aProvider) + 1;
00294     }
00295 
00296     static const char skinUrn[] = "urn:mozilla:skin:";
00297     if ((strcmp(aArc, "selectedSkin") == 0) &&
00298         (strncmp(aResourceValue, skinUrn, sizeof(skinUrn)-1) == 0)) {
00299 
00300         chopStart = sizeof(skinUrn) - 1;
00301         chopEnd = strlen(aProvider) + 1;
00302     }
00303 
00304     // strip off 'urn:mozilla:<foo>:' and ':<provider>'
00305     aResult = (aResourceValue + chopStart);
00306     aResult.Truncate(aResult.Length() - chopEnd);
00307         
00308 }