/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you 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 org.apache.openjpa.conf; | |
import java.util.Collection; | |
import java.util.Iterator; | |
import java.util.Map; | |
import org.apache.openjpa.kernel.Bootstrap; | |
import org.apache.openjpa.kernel.Broker; | |
import org.apache.openjpa.kernel.BrokerFactory; | |
import org.apache.openjpa.kernel.Query; | |
import org.apache.openjpa.lib.util.Options; | |
import org.apache.openjpa.lib.log.Log; | |
import org.apache.openjpa.lib.conf.MapConfigurationProvider; | |
import org.apache.openjpa.lib.conf.ConfigurationProvider; | |
import org.apache.openjpa.meta.ClassMetaData; | |
import org.apache.openjpa.meta.MetaDataRepository; | |
import org.apache.openjpa.meta.QueryMetaData; | |
import org.apache.openjpa.meta.SequenceMetaData; | |
/** | |
* Performs maintenance tasks on the metadata caches accessible via the | |
* {@link CacheMarshaller} architecture. | |
* | |
* @since 1.1.0 | |
*/ | |
public class MetaDataCacheMaintenance { | |
private final BrokerFactory factory; | |
private final OpenJPAConfiguration conf; | |
private final boolean devpath; | |
private Log log; | |
public static void main(String[] args) { | |
Options opts = new Options(); | |
args = opts.setFromCmdLine(args); | |
boolean devpath = opts.getBooleanProperty("scanDevPath", "ScanDevPath", | |
true); | |
ConfigurationProvider cp = new MapConfigurationProvider(opts); | |
BrokerFactory factory = Bootstrap.newBrokerFactory(cp, null); | |
try { | |
MetaDataCacheMaintenance maint = new MetaDataCacheMaintenance( | |
factory, devpath); | |
if (args.length != 1) { | |
usage(); | |
return; | |
} | |
if ("store".equals(args[0])) | |
maint.store(); | |
else if ("dump".equals(args[0])) | |
maint.dump(); | |
else | |
usage(); | |
} finally { | |
factory.close(); | |
} | |
} | |
/** | |
* @deprecated logging is routed to the logging system now. | |
*/ | |
public MetaDataCacheMaintenance(BrokerFactory factory, boolean devpath, | |
boolean verbose) { | |
this(factory, devpath); | |
} | |
/** | |
* @param factory The {@link BrokerFactory} for which cached metadata | |
* should be built. | |
* @param devpath Whether or not to scan the development environment paths | |
* to find persistent types to store. | |
*/ | |
public MetaDataCacheMaintenance(BrokerFactory factory, boolean devpath) { | |
this.factory = factory; | |
this.conf = factory.getConfiguration(); | |
this.devpath = devpath; | |
this.log = conf.getLog(OpenJPAConfiguration.LOG_TOOL); | |
} | |
public void setLog(Log log) { | |
this.log = log; | |
} | |
private static int usage() { | |
System.err.println("Usage: java MetaDataCacheMaintenance " + | |
"[-scanDevPath t|f] [-<openjpa.PropertyName> value] store | dump"); | |
return -1; | |
} | |
/** | |
* The metadata repository for the factory that this instance was | |
* constructed with will be serialized, along with any query | |
* compilations etc. that have been created for the factory. | |
*/ | |
public void store() { | |
MetaDataRepository repos = conf.getMetaDataRepositoryInstance(); | |
repos.setSourceMode(MetaDataRepository.MODE_ALL); | |
Collection types = repos.loadPersistentTypes(devpath, null); | |
for (Iterator iter = types.iterator(); iter.hasNext(); ) | |
repos.getMetaData((Class) iter.next(), null, true); | |
loadQueries(); | |
log.info("The following data will be stored: "); | |
log(repos, conf.getQueryCompilationCacheInstance()); | |
CacheMarshallersValue.getMarshallerById(conf, getClass().getName()) | |
.store(new Object[] { | |
repos, conf.getQueryCompilationCacheInstance() | |
}); | |
} | |
private void loadQueries() { | |
Broker broker = factory.newBroker(); | |
try { | |
QueryMetaData[] qmds = | |
conf.getMetaDataRepositoryInstance().getQueryMetaDatas(); | |
for (int i = 0; i < qmds.length; i++) | |
loadQuery(broker, qmds[i]); | |
} finally { | |
broker.close(); | |
} | |
} | |
private void loadQuery(Broker broker, QueryMetaData qmd) { | |
try { | |
Query q = broker.newQuery(qmd.getLanguage(), null); | |
qmd.setInto(q); | |
q.compile(); | |
} catch (Exception e) { | |
if (log.isTraceEnabled()) { | |
log.warn("Skipping named query " + qmd.getName() + ": " | |
+ e.getMessage(), e); | |
} else { | |
log.warn("Skipping named query " + qmd.getName() + ": " | |
+ e.getMessage()); | |
} | |
} | |
} | |
public void dump() { | |
Object[] os = (Object[]) | |
CacheMarshallersValue.getMarshallerById(conf, getClass().getName()) | |
.load(); | |
if (os == null) { | |
log.info("No cached data was found"); | |
return; | |
} | |
MetaDataRepository repos = (MetaDataRepository) os[0]; | |
Map qcc = (Map) os[1]; | |
log.info("The following data was found: "); | |
log(repos, qcc); | |
} | |
private void log(MetaDataRepository repos, Map qcc) { | |
ClassMetaData[] metas = repos.getMetaDatas(); | |
log.info(" Types: " + metas.length); | |
if (log.isTraceEnabled()) | |
for (int i = 0; i < metas.length; i++) | |
log.trace(" " + metas[i].getDescribedType().getName()); | |
QueryMetaData[] qmds = repos.getQueryMetaDatas(); | |
log.info(" Queries: " + qmds.length); | |
if (log.isTraceEnabled()) | |
for (int i = 0; i < qmds.length; i++) | |
log.trace(" " + qmds[i].getName() + ": " | |
+ qmds[i].getQueryString()); | |
SequenceMetaData[] smds = repos.getSequenceMetaDatas(); | |
log.info(" Sequences: " + smds.length); | |
if (log.isTraceEnabled()) | |
for (int i = 0; i < smds.length; i++) | |
log.trace(" " + smds[i].getName()); | |
log.info(" Compiled queries: " | |
+ (qcc == null ? "0" : "" + qcc.size())); | |
if (log.isTraceEnabled() && qcc != null) | |
for (Iterator iter = qcc.keySet().iterator(); iter.hasNext(); ) | |
log.trace(" " + iter.next()); | |
} | |
} |